Distributed Autonomous and Networked Control Lab
wikidb-distributed-autonomous-and-networked-control-lab
https://wikis.ece.iastate.edu/distributed-autonomous-and-networked-control-lab/index.php?title=Main_Page
MediaWiki 1.42.1
first-letter
Media
Special
Talk
User
User talk
Distributed Autonomous and Networked Control Lab
Distributed Autonomous and Networked Control Lab talk
File
File talk
MediaWiki
MediaWiki talk
Template
Template talk
Help
Help talk
Category
Category talk
Distributed Autonomous and Networked Control Lab Wiki
0
1
1
2016-03-08T22:05:45Z
MediaWiki default
0
wikitext
text/x-wiki
<big>'''MediaWiki has been successfully installed.'''</big>
Consult the [http://meta.wikimedia.org/wiki/Help:Contents User's Guide] for information on using the wiki software.
== Getting started ==
* [http://www.mediawiki.org/wiki/Manual:Configuration_settings Configuration settings list]
* [http://www.mediawiki.org/wiki/Manual:FAQ MediaWiki FAQ]
* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce MediaWiki release mailing list]
bd962048d95fbb6b6b514885867811db20a5476b
2
1
2016-06-25T18:05:17Z
Jnoronha
3
Wiki Home Page
wikitext
text/x-wiki
== <big>'''Distributed Autonomous and Networked Control Lab Wiki'''</big> ==
Welcome to the Distributed Autonomous and Networked Control Lab Wiki! Here you can find a wealth of information regarding the many projects we have running in the Lab.
Below are some of the projects we are working on.
----
'''
== Projects: ==
'''
[[Crazyflie Swarm]]
[[Robotic Agriculture Data Acquisition (RADA)]]
[[MicroCART]]
[[Camera System and VRPN]]
If you can't find what you're looking for please feel free to contribute.
Consult the [http://meta.wikimedia.org/wiki/Help:Contents User's Guide] for information on using the wiki software.
== Getting started ==
* [http://www.mediawiki.org/wiki/Manual:Configuration_settings Configuration settings list]
* [http://www.mediawiki.org/wiki/Manual:FAQ MediaWiki FAQ]
* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce MediaWiki release mailing list]
23bdc6c3291ff5c2f88388a75c81d49fd2b8b952
3
2
2016-06-25T18:06:11Z
Jnoronha
3
wikitext
text/x-wiki
== <big>'''Distributed Autonomous and Networked Control Lab Wiki'''</big> ==
Welcome to the Distributed Autonomous and Networked Control Lab Wiki! Here you can find a wealth of information regarding the many projects we have running in the Lab.
Below are some of the projects we are working on.
'''
== Projects: ==
'''
[[Crazyflie Swarm]]
[[Robotic Agriculture Data Acquisition (RADA)]]
[[MicroCART]]
[[Camera System and VRPN]]
If you can't find what you're looking for please feel free to contribute.
Consult the [http://meta.wikimedia.org/wiki/Help:Contents User's Guide] for information on using the wiki software.
== Getting started ==
* [http://www.mediawiki.org/wiki/Manual:Configuration_settings Configuration settings list]
* [http://www.mediawiki.org/wiki/Manual:FAQ MediaWiki FAQ]
* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce MediaWiki release mailing list]
f659eb5176979c86e59475e17c97e51bd31feb63
8
3
2016-06-25T18:49:21Z
Jnoronha
3
[[Main Page]] moved to [[Distributed Autonomous and Networked Control Lab Wiki]]: Renaming the Homepage
wikitext
text/x-wiki
== <big>'''Distributed Autonomous and Networked Control Lab Wiki'''</big> ==
Welcome to the Distributed Autonomous and Networked Control Lab Wiki! Here you can find a wealth of information regarding the many projects we have running in the Lab.
Below are some of the projects we are working on.
'''
== Projects: ==
'''
[[Crazyflie Swarm]]
[[Robotic Agriculture Data Acquisition (RADA)]]
[[MicroCART]]
[[Camera System and VRPN]]
If you can't find what you're looking for please feel free to contribute.
Consult the [http://meta.wikimedia.org/wiki/Help:Contents User's Guide] for information on using the wiki software.
== Getting started ==
* [http://www.mediawiki.org/wiki/Manual:Configuration_settings Configuration settings list]
* [http://www.mediawiki.org/wiki/Manual:FAQ MediaWiki FAQ]
* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce MediaWiki release mailing list]
f659eb5176979c86e59475e17c97e51bd31feb63
10
8
2016-06-25T18:50:23Z
Jnoronha
3
Removed Initial header since changed main page
wikitext
text/x-wiki
Welcome to the Distributed Autonomous and Networked Control Lab Wiki! Here you can find a wealth of information regarding the many projects we have running in the Lab.
Below are some of the projects we are working on.
'''
== Projects: ==
'''
[[Crazyflie Swarm]]
[[Robotic Agriculture Data Acquisition (RADA)]]
[[MicroCART]]
[[Camera System and VRPN]]
If you can't find what you're looking for please feel free to contribute.
Consult the [http://meta.wikimedia.org/wiki/Help:Contents User's Guide] for information on using the wiki software.
== Getting started ==
* [http://www.mediawiki.org/wiki/Manual:Configuration_settings Configuration settings list]
* [http://www.mediawiki.org/wiki/Manual:FAQ MediaWiki FAQ]
* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce MediaWiki release mailing list]
6ca26ba4236dd82ccbb7226525b0ae81ff55ff27
48
10
2016-07-12T16:41:20Z
Jnoronha
3
Added colon to 'below are some of the projects...'
wikitext
text/x-wiki
Welcome to the Distributed Autonomous and Networked Control Lab Wiki! Here you can find a wealth of information regarding the many projects we have running in the Lab.
Below are some of the projects we are working on:
'''
== Projects: ==
'''
[[Crazyflie Swarm]]
[[Robotic Agriculture Data Acquisition (RADA)]]
[[MicroCART]]
[[Camera System and VRPN]]
If you can't find what you're looking for please feel free to contribute.
Consult the [http://meta.wikimedia.org/wiki/Help:Contents User's Guide] for information on using the wiki software.
== Getting started ==
* [http://www.mediawiki.org/wiki/Manual:Configuration_settings Configuration settings list]
* [http://www.mediawiki.org/wiki/Manual:FAQ MediaWiki FAQ]
* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce MediaWiki release mailing list]
04829c1b139875b5566055386125a413b79de76f
Crazyflie Swarm
0
2
4
2016-06-25T18:20:25Z
Jnoronha
3
Crazyflie Swarm Home Page
wikitext
text/x-wiki
== <big>'''Crazyflie Swarm '''</big>==
The Crazyflie Swarm is a Networked Control platform designed for students to learn more about control and for researchers that wish to apply their research in practice. The platform was started during the Summer of 2015 and continues to be in development.
Here you will find descriptions on how the platform works, how you can use it, and how you can get involved in developing the platform further!
== Background ==
The Crazyflie Swarm platform is based off of the ''Crazyflie'' Nano-quadcopter produced and maintained by Bitcraze[https://www.bitcraze.io/]. The ''Crazyflie'' is completely open-source so we are able to look at and modify any part of the code.
6d43a2b39f56d644192965b9ed1fe8a3956d8532
5
4
2016-06-25T18:31:54Z
Jnoronha
3
Added client firmware and radio to background, and linked homepage of Bitcraze Wiki
wikitext
text/x-wiki
== <big>'''Crazyflie Swarm '''</big>==
The Crazyflie Swarm is a Networked Control platform designed for students to learn more about control and for researchers that wish to apply their research in practice. The platform was started during the Summer of 2015 and continues to be in development.
Here you will find descriptions on how the platform works, how you can use it, and how you can get involved in developing the platform further!
== Background ==
The Crazyflie Swarm platform is based off of the ''Crazyflie'' Nano-quadcopter produced and maintained by Bitcraze[https://www.bitcraze.io/]. The ''Crazyflie'' is completely open-source so we are able to look at and modify any part of the code and customize it to our needs.
There are 3 components that make up the framework of the Crazyflie platform:
*[[PC Client Software]]
*[[Firmware]]
*[[USB Radio]]
== [https://wiki.bitcraze.io/ Bitcraze Wiki] ==
Bitcraze maintains their own wiki on the many Crazyflie systems. If you can't find what you are looking for here, chances are they will have something to help.
09b82172de16f13cc8a0e492c8898dfe982b8f61
6
5
2016-06-25T18:32:45Z
Jnoronha
3
Changed Bitcraze extern link to include full text
wikitext
text/x-wiki
== <big>'''Crazyflie Swarm '''</big>==
The Crazyflie Swarm is a Networked Control platform designed for students to learn more about control and for researchers that wish to apply their research in practice. The platform was started during the Summer of 2015 and continues to be in development.
Here you will find descriptions on how the platform works, how you can use it, and how you can get involved in developing the platform further!
== Background ==
The Crazyflie Swarm platform is based off of the ''Crazyflie'' Nano-quadcopter produced and maintained by [https://www.bitcraze.io/ Bitcraze]. The ''Crazyflie'' is completely open-source so we are able to look at and modify any part of the code and customize it to our needs.
There are 3 components that make up the framework of the Crazyflie platform:
*[[PC Client Software]]
*[[Firmware]]
*[[USB Radio]]
== [https://wiki.bitcraze.io/ Bitcraze Wiki] ==
Bitcraze maintains their own wiki on the many Crazyflie systems. If you can't find what you are looking for here, chances are they will have something to help.
d794248507b500bef09efc5e338681597eabed90
7
6
2016-06-25T18:36:33Z
Jnoronha
3
Added FAQ page link
wikitext
text/x-wiki
== <big>'''Crazyflie Swarm '''</big>==
The Crazyflie Swarm is a Networked Control platform designed for students to learn more about control and for researchers that wish to apply their research in practice. The platform was started during the Summer of 2015 and continues to be in development.
Here you will find descriptions on how the platform works, how you can use it, and how you can get involved in developing the platform further!
== Background ==
The Crazyflie Swarm platform is based off of the ''Crazyflie'' Nano-quadcopter produced and maintained by [https://www.bitcraze.io/ Bitcraze]. The ''Crazyflie'' is completely open-source so we are able to look at and modify any part of the code and customize it to our needs.
There are 3 components that make up the framework of the Crazyflie platform:
*[[PC Client Software]]
*[[Firmware]]
*[[USB Radio]]
== Frequently Asked Questions ==
For help with common problems and troubleshooting please see the [[FAQ]].
== [https://wiki.bitcraze.io/ Bitcraze Wiki] ==
Bitcraze maintains their own wiki on the many Crazyflie systems. If you can't find what you are looking for here, chances are they will have something to help.
6fbd8d65c8d5ff0e8d835a6b0a87f811c811ff94
11
7
2016-06-25T18:51:33Z
Jnoronha
3
Removed main header (redundant
wikitext
text/x-wiki
The Crazyflie Swarm is a Networked Control platform designed for students to learn more about control and for researchers that wish to apply their research in practice. The platform was started during the Summer of 2015 and continues to be in development.
Here you will find descriptions on how the platform works, how you can use it, and how you can get involved in developing the platform further!
== Background ==
The Crazyflie Swarm platform is based off of the ''Crazyflie'' Nano-quadcopter produced and maintained by [https://www.bitcraze.io/ Bitcraze]. The ''Crazyflie'' is completely open-source so we are able to look at and modify any part of the code and customize it to our needs.
There are 3 components that make up the framework of the Crazyflie platform:
*[[PC Client Software]]
*[[Firmware]]
*[[USB Radio]]
== Frequently Asked Questions ==
For help with common problems and troubleshooting please see the [[FAQ]].
== [https://wiki.bitcraze.io/ Bitcraze Wiki] ==
Bitcraze maintains their own wiki on the many Crazyflie systems. If you can't find what you are looking for here, chances are they will have something to help.
810ea5bb057d2f4366105386340c2f3b4e00e9bc
12
11
2016-06-25T19:31:45Z
Jnoronha
3
Added 3rd heading major platform components and 2nd heading 'modifying the platform'
wikitext
text/x-wiki
The Crazyflie Swarm is a Networked Control platform designed for students to learn more about control and for researchers that wish to apply their research in practice. The platform was started during the Summer of 2015 and continues to be in development.
Here you will find descriptions on how the platform works, how you can use it, and how you can get involved in developing the platform further!
== Background ==
The Crazyflie Swarm platform is based off of the ''Crazyflie'' Nano-quadcopter produced and maintained by [https://www.bitcraze.io/ Bitcraze]. The ''Crazyflie'' is completely open-source so we are able to look at and modify any part of the code and customize it to our needs.
==='''Major Platform Components:'''===
*[[PC Client Software]]
*[[Firmware]]
*[[USB Radio]]
== Modifying the Platform ==
== Frequently Asked Questions ==
For help with common problems and troubleshooting please see the [[FAQ]].
== [https://wiki.bitcraze.io/ Bitcraze Wiki] ==
Bitcraze maintains their own wiki on the many Crazyflie systems. If you can't find what you are looking for here, chances are they will have something to help.
4c5444410a5b11407496db75c92ebf25b359e3e3
13
12
2016-06-25T19:33:27Z
Jnoronha
3
slight intro modification
wikitext
text/x-wiki
The Crazyflie Swarm is a Networked Control platform designed for students to learn more about control and for researchers that wish to apply their research in practice. Platform development was started during the Summer of 2015 and continues to this day.
Here you will find descriptions on how the platform works, how you can use it, and how you can get involved in developing the platform further!
== Background ==
The Crazyflie Swarm platform is based off of the ''Crazyflie'' Nano-quadcopter produced and maintained by [https://www.bitcraze.io/ Bitcraze]. The ''Crazyflie'' is completely open-source so we are able to look at and modify any part of the code and customize it to our needs.
==='''Major Platform Components:'''===
*[[PC Client Software]]
*[[Firmware]]
*[[USB Radio]]
== Modifying the Platform ==
== Frequently Asked Questions ==
For help with common problems and troubleshooting please see the [[FAQ]].
== [https://wiki.bitcraze.io/ Bitcraze Wiki] ==
Bitcraze maintains their own wiki on the many Crazyflie systems. If you can't find what you are looking for here, chances are they will have something to help.
977cb9c12248b20de98cc1259063ad6613a0fabd
15
13
2016-06-25T19:54:19Z
Jnoronha
3
/* Background */ Added High level architecture figure
wikitext
text/x-wiki
The Crazyflie Swarm is a Networked Control platform designed for students to learn more about control and for researchers that wish to apply their research in practice. Platform development was started during the Summer of 2015 and continues to this day.
Here you will find descriptions on how the platform works, how you can use it, and how you can get involved in developing the platform further!
== Background ==
The Crazyflie Swarm platform is based off of the ''Crazyflie'' Nano-quadcopter produced and maintained by [https://www.bitcraze.io/ Bitcraze]. The ''Crazyflie'' is completely open-source so we are able to look at and modify any part of the code and customize it to our needs.
==='''Major Platform Components:'''===
[[Image: High_Level_Figure_(Single_Radio_Single_Crazyflie_NO_NUMBERS_CROPPED).jpg|thumb|right|A high level overview of the Crazyflie Platform]]
*[[PC Client Software]]
*[[Firmware]]
*[[USB Radio]]
== Modifying the Platform ==
== Frequently Asked Questions ==
For help with common problems and troubleshooting please see the [[FAQ]].
== [https://wiki.bitcraze.io/ Bitcraze Wiki] ==
Bitcraze maintains their own wiki on the many Crazyflie systems. If you can't find what you are looking for here, chances are they will have something to help.
d705dffa8fc4c16df38ad4e7a1ff35c5af79384c
16
15
2016-06-27T18:28:15Z
Jnoronha
3
Added list of topics for modifying the platform (to be filled in)
wikitext
text/x-wiki
The Crazyflie Swarm is a Networked Control platform designed for students to learn more about control and for researchers that wish to apply their research in practice. Platform development was started during the Summer of 2015 and continues to this day.
Here you will find descriptions on how the platform works, how you can use it, and how you can get involved in developing the platform further!
== Background ==
The Crazyflie Swarm platform is based off of the ''Crazyflie'' Nano-quadcopter produced and maintained by [https://www.bitcraze.io/ Bitcraze]. The ''Crazyflie'' is completely open-source so we are able to look at and modify any part of the code and customize it to our needs.
=== Major Platform Components: ===
[[Image: High_Level_Figure_(Single_Radio_Single_Crazyflie_NO_NUMBERS_CROPPED).jpg|thumb|right|A high level overview of the Crazyflie Platform]]
*[[PC Client Software]]
*[[Firmware]]
*[[USB Radio]]
== Modifying the Platform ==
*[[PID Controller]]
*[[Logging]]
*[[Keyboard Commands]]
*[[Radio Channels (Link to Section in USB Radio)]]
*[[Flight Modes]]
*[[Callbacks]]
*[[Adding a Crazyflie]]
*[[:Firmware]]
== Frequently Asked Questions ==
For help with common problems and troubleshooting please see the [[FAQ]].
== [https://wiki.bitcraze.io/ Bitcraze Wiki] ==
Bitcraze maintains their own wiki on the many Crazyflie systems. If you can't find what you are looking for here, chances are they will have something to help.
28056276d7ce0c5f7c4a358193c6a7dfb7098d0d
17
16
2016-06-27T18:36:13Z
Jnoronha
3
Changed PID controller topic to more general "Controller" modification
wikitext
text/x-wiki
The Crazyflie Swarm is a Networked Control platform designed for students to learn more about control and for researchers that wish to apply their research in practice. Platform development was started during the Summer of 2015 and continues to this day.
Here you will find descriptions on how the platform works, how you can use it, and how you can get involved in developing the platform further!
== Background ==
The Crazyflie Swarm platform is based off of the ''Crazyflie'' Nano-quadcopter produced and maintained by [https://www.bitcraze.io/ Bitcraze]. The ''Crazyflie'' is completely open-source so we are able to look at and modify any part of the code and customize it to our needs.
=== Major Platform Components: ===
[[Image: High_Level_Figure_(Single_Radio_Single_Crazyflie_NO_NUMBERS_CROPPED).jpg|thumb|right|A high level overview of the Crazyflie Platform]]
*[[PC Client Software]]
*[[Firmware]]
*[[USB Radio]]
== Modifying the Platform ==
*[[Controller]]
*[[Logging]]
*[[Keyboard Commands]]
*[[Radio Channels (Link to Section in USB Radio)]]
*[[Flight Modes]]
*[[Callbacks]]
*[[Adding a Crazyflie]]
*[[:Firmware]]
== Frequently Asked Questions ==
For help with common problems and troubleshooting please see the [[FAQ]].
== [https://wiki.bitcraze.io/ Bitcraze Wiki] ==
Bitcraze maintains their own wiki on the many Crazyflie systems. If you can't find what you are looking for here, chances are they will have something to help.
6c62bb7a962a0c336fc876500c407d0199020e33
Main Page
0
3
9
2016-06-25T18:49:21Z
Jnoronha
3
[[Main Page]] moved to [[Distributed Autonomous and Networked Control Lab Wiki]]: Renaming the Homepage
wikitext
text/x-wiki
#REDIRECT [[Distributed Autonomous and Networked Control Lab Wiki]]
c68032b4d3ee00c7b348a2dcbe17a466bcdca0c8
File:High Level Figure (Single Radio Single Crazyflie NO NUMBERS CROPPED).jpg
6
4
14
2016-06-25T19:48:10Z
Jnoronha
3
High Level Crazyflie System layout
wikitext
text/x-wiki
High Level Crazyflie System layout
b73937b5e696ddab6f690bf4dd24d1b591f3e116
Controller
0
5
18
2016-06-27T18:55:05Z
Jnoronha
3
Added intro and Subsections for Firmware controllers and Client Controllers
wikitext
text/x-wiki
The Crazyflie platform is completely customizable when it comes to the control design. As long as the controller can be written in C or C++, we can implement it in the Platform. This applies to both the controllers run on the PC Client and the controllers run on the Firmware of the Crazyflie.
Below you will find documentation on the different types of Controllers that have been applied to the platform, organized by their location in the Platform.
== PC Client ==
=== PID Controller ===
== Firmware ==
=== PID Controller ===
a4987e836f450aeddc707c87ecafc49ec855ed87
19
18
2016-06-27T18:59:27Z
Jnoronha
3
wikitext
text/x-wiki
The Crazyflie platform is completely customizable when it comes to the control design. As long as the controller can be written in C or C++, we can implement it in the Platform. This applies to both the controllers run on the PC Client and the controllers run on the Firmware of the Crazyflie.
Below you will find documentation on the different types of Controllers that have been applied to the platform, organized by their location in the Platform.
== PC Client ==
=== PID Controllers (Position and Yaw) ===
The first controller implemented on the Client was a PID controller used to stabilize the Crazyflie's position in X, Y, and Z.
== Firmware ==
=== PID Controllers (Angular Rotation) ===
8d26f22dc9c21bd64fb2b81199966114b7ecaf82
20
19
2016-06-27T19:26:48Z
Jnoronha
3
Describing original Firmware Control Architecture
wikitext
text/x-wiki
The Crazyflie platform is completely customizable when it comes to the control design. As long as the controller can be written in C or C++, we can implement it in the Platform. This applies to both the controllers run on the PC Client and the controllers run on the Firmware of the Crazyflie. Originally the only controllers in the Platform were Firmware PID's that controlled the angular position and rates of the Crazyflie for hand flight. The original controller layout can be seen in '''Figure 1'''.
Below you will find documentation on the different types of Controllers that have been applied to the platform, organized by their location in the Platform.
== PC Client ==
=== PID Controllers (Position and Yaw) ===
The first controller implemented on the Client was a PID controller used to stabilize the Crazyflie's position in X, Y, and Z.
== Firmware ==
=== Original PID Controllers (Angular Rotation) ===
509e35341e48b9f5d5331913d59c28460bc5cdf3
USB Radio
0
6
21
2016-07-09T16:58:00Z
Jnoronha
3
Page setup and adding basic info
wikitext
text/x-wiki
The USB Radio Dongle acts as the bridge between the Client and the Firmware. It sends control setpoints generated from the Client to the Firmware controllers, as well as receives sensor data from the Firmware to the Client for logging.
== Modifying the Radio ==
The Radio functions can be found in the CCrazyRadio.cpp source file.
=== Changing Radio Channel ===
13e7ccea98d6692b0113cd76da22f7dc0d6ef6de
22
21
2016-07-09T18:24:06Z
Jnoronha
3
Added first 3 steps of radio initialization
wikitext
text/x-wiki
The USB Radio Dongle acts as the bridge between the Client and the Firmware. It sends control setpoints generated from the Client to the Firmware controllers, as well as receives sensor data from the Firmware to the Client for logging.
== Modifying the Radio ==
The Radio functions can be found in the [[CCrazyRadio.cpp]] source file.
=== Radio Initialization ===
:1. Create CrazyRadio Pointers and Crazyflie Pointers
<blockquote>
<code>
''CCrazyRadio *crRadio1 = 0;<br/>''
''CCrazyRadio *crRadio2 = 0;<br/>''
<br/>
''CCrazyflie *cflieCopter1 = 0;''<br/>
''CCrazyflie *cflieCopter2 = 0;''<br/>
''CCrazyflie *cflieCopter3 = 0;''<br/>
''CCrazyflie *cflieCopter4 = 0;''<br/>
</code>
</blockquote>
'''Note:''' You must have a pointer for EACH Radio you want to initialize.
:2. Initialize First CrazyRadio
<blockquote>
<code>
crRadio1 = new CCrazyRadio(0); // dongle number (starting at 0)<br/>
if( crRadio1->startRadio() ) //assigns pointer to USB location<br/>
{<br/>
cflieCopter1 = new CCrazyflie(crRadio1, 5); //Assigns Crazyflie1 to Radio1 on Channel 5 <br/>
cflieCopter2 = new CCrazyflie(crRadio1, 80); //Assigns Crazyflie2 to Radio1 on Channel 80<br/>
}<br/>
else <br/>
{ <br/>
std::cerr << "Could not connect to dongle 1. Did you plug it in?" << std::endl; <br/>
exit(-1); <br/>
} <br/>
usleep(10000);<br/>
<br/>
</code>
</blockquote>
:3. Initialize Second CrazyRadio (repeat as necessary...)
<blockquote>
<code>
crRadio2 = new CCrazyRadio(1); // dongle number<br/>
<br/>
if( crRadio2->startRadio() ) <br/>
{ <br/>
cflieCopter3 = new CCrazyflie(crRadio2, 25); <br/>
cflieCopter4 = new CCrazyflie(crRadio2, 45); <br/>
} <br/>
else <br/>
{ <br/>
std::cerr << "Could not connect to dongle 2. Did you plug it in?" << std::endl; <br/>
exit(-1); <br/>
} <br/>
usleep(10000);
</code>
</blockquote>
=== Changing Radio Channel ===
34af1e3ac8303f240bd5dd3e0d03728f57a85838
23
22
2016-07-09T18:33:22Z
Jnoronha
3
Formatted code to have boxes around them
wikitext
text/x-wiki
The USB Radio Dongle acts as the bridge between the Client and the Firmware. It sends control setpoints generated from the Client to the Firmware controllers, as well as receives sensor data from the Firmware to the Client for logging.
== Modifying the Radio ==
The Radio functions can be found in the [[CCrazyRadio.cpp]] source file.
=== Radio Initialization ===
:1. Create CrazyRadio Pointers and Crazyflie Pointers
<blockquote>
<code>
<pre>CCrazyRadio *crRadio1 = 0;
CCrazyRadio *crRadio2 = 0;
CCrazyflie *cflieCopter1 = 0;
CCrazyflie *cflieCopter2 = 0;
CCrazyflie *cflieCopter3 = 0;
CCrazyflie *cflieCopter4 = 0;
</pre>
</code>
</blockquote>
'''Note:''' You must have a pointer for EACH Radio you want to initialize.
:2. Initialize First CrazyRadio
<blockquote>
<code>
<pre>
crRadio1 = new CCrazyRadio(0); // dongle number (starting at 0)
if( crRadio1->startRadio() ) //assigns pointer to USB location
{
cflieCopter1 = new CCrazyflie(crRadio1, 5); //Assigns Crazyflie1 to Radio1 on Channel 5
cflieCopter2 = new CCrazyflie(crRadio1, 80); //Assigns Crazyflie2 to Radio1 on Channel 80
}
else
{
std::cerr << "Could not connect to dongle 1. Did you plug it in?" << std::endl;
exit(-1);
}
usleep(10000);
</pre>
</code>
</blockquote>
:3. Initialize Second CrazyRadio (repeat as necessary...)
<blockquote>
<code>
<pre>
crRadio2 = new CCrazyRadio(1); // dongle number
if( crRadio2->startRadio() )
{
cflieCopter3 = new CCrazyflie(crRadio2, 25); //Assigns Crazyflie3 to Radio2 on Channel 25
cflieCopter4 = new CCrazyflie(crRadio2, 45); //Assigns Crazyflie4 to Radio2 on Channel 45
}
else
{
std::cerr << "Could not connect to dongle 2. Did you plug it in?" << std::endl;
exit(-1);
}
usleep(10000);
</pre>
</code>
</blockquote>
=== Changing Radio Channel ===
0ac12629730434286c4814a884623da0b301b234
24
23
2016-07-09T18:42:08Z
Jnoronha
3
Finished Radio Initialization Section
wikitext
text/x-wiki
The USB Radio Dongle acts as the bridge between the Client and the Firmware. It sends control setpoints generated from the Client to the Firmware controllers, as well as receives sensor data from the Firmware to the Client for logging.
== Modifying the Radio ==
The Radio functions can be found in the [[CCrazyRadio.cpp]] source file.
=== Radio Initialization ===
:1. Create CrazyRadio Pointers and Crazyflie Pointers
<blockquote>
<code>
<pre>CCrazyRadio *crRadio1 = 0;
CCrazyRadio *crRadio2 = 0;
CCrazyflie *cflieCopter1 = 0;
CCrazyflie *cflieCopter2 = 0;
CCrazyflie *cflieCopter3 = 0;
CCrazyflie *cflieCopter4 = 0;
</pre>
</code>
</blockquote>
'''Note:''' You must have a pointer for EACH Radio you want to initialize.
:2. Initialize First CrazyRadio
<blockquote>
<code>
<pre>
crRadio1 = new CCrazyRadio(0); // dongle number (starting at 0)
if( crRadio1->startRadio() ) //assigns pointer to USB location
{
cflieCopter1 = new CCrazyflie(crRadio1, 5); //Assigns Crazyflie1 to Radio1 on Channel 5
cflieCopter2 = new CCrazyflie(crRadio1, 80); //Assigns Crazyflie2 to Radio1 on Channel 80
}
else
{
std::cerr << "Could not connect to dongle 1. Did you plug it in?" << std::endl;
exit(-1);
}
usleep(10000);
</pre>
</code>
</blockquote>
:3. Initialize Second CrazyRadio (repeat as necessary...)
<blockquote>
<code>
<pre>
crRadio2 = new CCrazyRadio(1); // dongle number
if( crRadio2->startRadio() )
{
cflieCopter3 = new CCrazyflie(crRadio2, 25); //Assigns Crazyflie3 to Radio2 on Channel 25
cflieCopter4 = new CCrazyflie(crRadio2, 45); //Assigns Crazyflie4 to Radio2 on Channel 45
}
else
{
std::cerr << "Could not connect to dongle 2. Did you plug it in?" << std::endl;
exit(-1);
}
usleep(10000);
</pre>
</code>
</blockquote>
:4. (OPTIONAL) Modify Radio Parameters
<blockquote>
<code>
<pre>
crRadio1->setARDTime(2000); //Sets Wait Time (in μs) between Packet Retries (**MUST BE IN INCREMENTS OF 250**)
crRadio1->setARC(0); //Sets Number of times Retries Packet Send
crRadio1->setPower(P_0DBM); //Sets Radio Power (See CCrazyRadio.h for allowed ENUM values)
</pre>
</code>
</blockquote>
:5. '''Always''' Delete Radio Pointers Before Ending Program
<blockquote>
<code>
<pre>
delete crRadio1;
delete crRadio2;
</pre>
</code>
</blockquote>
'''Note:''' If you don't delete the pointers then you need to unplug the Radio and plug it back into the USB!
=== Changing Radio Channel ===
e37c6947cb34d638877c7777ee666c3d0e2b4051
25
24
2016-07-09T18:43:25Z
Jnoronha
3
Removed tabs on delete radio and param modification
wikitext
text/x-wiki
The USB Radio Dongle acts as the bridge between the Client and the Firmware. It sends control setpoints generated from the Client to the Firmware controllers, as well as receives sensor data from the Firmware to the Client for logging.
== Modifying the Radio ==
The Radio functions can be found in the [[CCrazyRadio.cpp]] source file.
=== Radio Initialization ===
:1. Create CrazyRadio Pointers and Crazyflie Pointers
<blockquote>
<code>
<pre>CCrazyRadio *crRadio1 = 0;
CCrazyRadio *crRadio2 = 0;
CCrazyflie *cflieCopter1 = 0;
CCrazyflie *cflieCopter2 = 0;
CCrazyflie *cflieCopter3 = 0;
CCrazyflie *cflieCopter4 = 0;
</pre>
</code>
</blockquote>
'''Note:''' You must have a pointer for EACH Radio you want to initialize.
:2. Initialize First CrazyRadio
<blockquote>
<code>
<pre>
crRadio1 = new CCrazyRadio(0); // dongle number (starting at 0)
if( crRadio1->startRadio() ) //assigns pointer to USB location
{
cflieCopter1 = new CCrazyflie(crRadio1, 5); //Assigns Crazyflie1 to Radio1 on Channel 5
cflieCopter2 = new CCrazyflie(crRadio1, 80); //Assigns Crazyflie2 to Radio1 on Channel 80
}
else
{
std::cerr << "Could not connect to dongle 1. Did you plug it in?" << std::endl;
exit(-1);
}
usleep(10000);
</pre>
</code>
</blockquote>
:3. Initialize Second CrazyRadio (repeat as necessary...)
<blockquote>
<code>
<pre>
crRadio2 = new CCrazyRadio(1); // dongle number
if( crRadio2->startRadio() )
{
cflieCopter3 = new CCrazyflie(crRadio2, 25); //Assigns Crazyflie3 to Radio2 on Channel 25
cflieCopter4 = new CCrazyflie(crRadio2, 45); //Assigns Crazyflie4 to Radio2 on Channel 45
}
else
{
std::cerr << "Could not connect to dongle 2. Did you plug it in?" << std::endl;
exit(-1);
}
usleep(10000);
</pre>
</code>
</blockquote>
:4. (OPTIONAL) Modify Radio Parameters
<blockquote>
<code>
<pre>
crRadio1->setARDTime(2000); //Sets Wait Time (in μs) between Packet Retries (**MUST BE IN INCREMENTS OF 250**)
crRadio1->setARC(0); //Sets Number of times Retries Packet Send
crRadio1->setPower(P_0DBM); //Sets Radio Power (See CCrazyRadio.h for allowed ENUM values)
</pre>
</code>
</blockquote>
:5. '''Always''' Delete Radio Pointers Before Ending Program
<blockquote>
<code>
<pre>
delete crRadio1;
delete crRadio2;
</pre>
</code>
</blockquote>
'''Note:''' If you don't delete the pointers then you need to unplug the Radio and plug it back into the USB!
=== Changing Radio Channel ===
bc4196fa430a5f9e606d0808c7ecc23ddffee58e
26
25
2016-07-09T18:48:40Z
Jnoronha
3
Added brief description to Radio init
wikitext
text/x-wiki
The USB Radio Dongle acts as the bridge between the Client and the Firmware. It sends control setpoints generated from the Client to the Firmware controllers, as well as receives sensor data from the Firmware to the Client for logging.
== Modifying the Radio ==
The Radio functions can be found in the [[CCrazyRadio.cpp]] source file.
=== Radio Initialization ===
The following steps are how to Initialize a Radio. This code is currently run at the start of <code> main </code> in [[eris_vrpn.cpp]]. The process below can be extended to '''any number of Radios''' (currently 2 Radios shown)
:1. Create CrazyRadio Pointers and Crazyflie Pointers
<blockquote>
<code>
<pre>
CCrazyRadio *crRadio1 = 0;
CCrazyRadio *crRadio2 = 0;
CCrazyflie *cflieCopter1 = 0;
CCrazyflie *cflieCopter2 = 0;
CCrazyflie *cflieCopter3 = 0;
CCrazyflie *cflieCopter4 = 0;
</pre>
</code>
</blockquote>
'''Note:''' You must have a pointer for EACH Radio you want to initialize.
:2. Initialize First CrazyRadio
<blockquote>
<code>
<pre>
crRadio1 = new CCrazyRadio(0); // dongle number (starting at 0)
if( crRadio1->startRadio() ) //assigns pointer to USB location
{
cflieCopter1 = new CCrazyflie(crRadio1, 5); //Assigns Crazyflie1 to Radio1 on Channel 5
cflieCopter2 = new CCrazyflie(crRadio1, 80); //Assigns Crazyflie2 to Radio1 on Channel 80
}
else
{
std::cerr << "Could not connect to dongle 1. Did you plug it in?" << std::endl;
exit(-1);
}
usleep(10000);
</pre>
</code>
</blockquote>
:3. Initialize Second CrazyRadio (repeat as necessary...)
<blockquote>
<code>
<pre>
crRadio2 = new CCrazyRadio(1); // dongle number
if( crRadio2->startRadio() )
{
cflieCopter3 = new CCrazyflie(crRadio2, 25); //Assigns Crazyflie3 to Radio2 on Channel 25
cflieCopter4 = new CCrazyflie(crRadio2, 45); //Assigns Crazyflie4 to Radio2 on Channel 45
}
else
{
std::cerr << "Could not connect to dongle 2. Did you plug it in?" << std::endl;
exit(-1);
}
usleep(10000);
</pre>
</code>
</blockquote>
:4. (OPTIONAL) Modify Radio Parameters
<blockquote>
<code>
<pre>
crRadio1->setARDTime(2000); //Sets Wait Time (in μs) between Packet Retries (**MUST BE IN INCREMENTS OF 250**)
crRadio1->setARC(0); //Sets Number of times Retries Packet Send
crRadio1->setPower(P_0DBM); //Sets Radio Power (See CCrazyRadio.h for allowed ENUM values)
</pre>
</code>
</blockquote>
:5. '''Always''' Delete Radio Pointers Before Ending Program
<blockquote>
<code>
<pre>
delete crRadio1;
delete crRadio2;
</pre>
</code>
</blockquote>
'''Note:''' If you don't delete the pointers then you need to unplug the Radio and plug it back into the USB!
=== Changing Radio Channel ===
55cc296855b6fd5798824fa4ea7b471b561b5c52
28
26
2016-07-09T19:44:19Z
Jnoronha
3
added low level channel set and description
wikitext
text/x-wiki
The USB Radio Dongle acts as the bridge between the Client and the Firmware. It sends control setpoints generated from the Client to the Firmware controllers, as well as receives sensor data from the Firmware to the Client for logging.
== Modifying the Radio ==
The Radio functions can be found in the [[CCrazyRadio.cpp]] source file.
=== Radio Initialization ===
The following steps are how to Initialize a Radio. This code is currently run at the start of <code> main </code> in [[eris_vrpn.cpp]]. The process below can be extended to '''any number of Radios''' (currently 2 Radios shown)
:1. Create CrazyRadio Pointers and Crazyflie Pointers
<blockquote>
<code>
<pre>
CCrazyRadio *crRadio1 = 0;
CCrazyRadio *crRadio2 = 0;
CCrazyflie *cflieCopter1 = 0;
CCrazyflie *cflieCopter2 = 0;
CCrazyflie *cflieCopter3 = 0;
CCrazyflie *cflieCopter4 = 0;
</pre>
</code>
</blockquote>
'''Note:''' You must have a pointer for EACH Radio you want to initialize.
:2. Initialize First CrazyRadio
<blockquote>
<code>
<pre>
crRadio1 = new CCrazyRadio(0); // dongle number (starting at 0)
if( crRadio1->startRadio() ) //assigns pointer to USB location
{
cflieCopter1 = new CCrazyflie(crRadio1, 5); //Assigns Crazyflie1 to Radio1 on Channel 5
cflieCopter2 = new CCrazyflie(crRadio1, 80); //Assigns Crazyflie2 to Radio1 on Channel 80
}
else
{
std::cerr << "Could not connect to dongle 1. Did you plug it in?" << std::endl;
exit(-1);
}
usleep(10000);
</pre>
</code>
</blockquote>
:3. Initialize Second CrazyRadio (repeat as necessary...)
<blockquote>
<code>
<pre>
crRadio2 = new CCrazyRadio(1); // dongle number
if( crRadio2->startRadio() )
{
cflieCopter3 = new CCrazyflie(crRadio2, 25); //Assigns Crazyflie3 to Radio2 on Channel 25
cflieCopter4 = new CCrazyflie(crRadio2, 45); //Assigns Crazyflie4 to Radio2 on Channel 45
}
else
{
std::cerr << "Could not connect to dongle 2. Did you plug it in?" << std::endl;
exit(-1);
}
usleep(10000);
</pre>
</code>
</blockquote>
:4. (OPTIONAL) Modify Radio Parameters
<blockquote>
<code>
<pre>
crRadio1->setARDTime(2000); //Sets Wait Time (in μs) between Packet Retries (**MUST BE IN INCREMENTS OF 250**)
crRadio1->setARC(0); //Sets Number of times Retries Packet Send
crRadio1->setPower(P_0DBM); //Sets Radio Power (See CCrazyRadio.h for allowed ENUM values)
</pre>
</code>
</blockquote>
:5. '''Always''' Delete Radio Pointers Before Ending Program
<blockquote>
<code>
<pre>
delete crRadio1;
delete crRadio2;
</pre>
</code>
</blockquote>
'''Note:''' If you don't delete the pointers then you need to unplug the Radio and plug it back into the USB!
=== Changing Radio Channel ===
Changing the Radio Channel is easy, all you need to do is call the function:
<blockquote>
<code>
<pre>
crRadio1->setChannel( cflieCopter1->radioChannel() ); //Sets Radio channel to whatever value cflieCopter1 was assigned (The input can be replaced with a constant if needed)
</pre>
</code>
</blockquote>
==== How does it work? ====
The low level implementation of the <code> setChannel </code> function looks like this:
<blockquote>
<code>
<pre>
void CCrazyRadio::setChannel(int nChannel) {
if( ALL_THE_DEBUG ) printf( "%s(nChannel:%d)\n", __FUNCTION__, nChannel );
this->writeControl(NULL, 0, 0x01, nChannel, 0);
}
</pre>
</code>
</blockquote>
Which is using a libusb command <code> writeControl </code> to find the specific USB address of the Radio and write a new Channel to that USB device. The specific values plugged into this function will need to be looked up if you plan on working at this level.
e8230704b069d79d326458143d32cc512819c919
29
28
2016-07-09T20:01:32Z
Jnoronha
3
Added Directory Footer
wikitext
text/x-wiki
[[Media:Example.ogg]]The USB Radio Dongle acts as the bridge between the Client and the Firmware. It sends control setpoints generated from the Client to the Firmware controllers, as well as receives sensor data from the Firmware to the Client for logging.
== Modifying the Radio ==
The Radio functions can be found in the [[CCrazyRadio.cpp]] source file.
=== Radio Initialization ===
The following steps are how to Initialize a Radio. This code is currently run at the start of <code> main </code> in [[eris_vrpn.cpp]]. The process below can be extended to '''any number of Radios''' (currently 2 Radios shown)
:1. Create CrazyRadio Pointers and Crazyflie Pointers
<blockquote>
<code>
<pre>
CCrazyRadio *crRadio1 = 0;
CCrazyRadio *crRadio2 = 0;
CCrazyflie *cflieCopter1 = 0;
CCrazyflie *cflieCopter2 = 0;
CCrazyflie *cflieCopter3 = 0;
CCrazyflie *cflieCopter4 = 0;
</pre>
</code>
</blockquote>
'''Note:''' You must have a pointer for EACH Radio you want to initialize.
:2. Initialize First CrazyRadio
<blockquote>
<code>
<pre>
crRadio1 = new CCrazyRadio(0); // dongle number (starting at 0)
if( crRadio1->startRadio() ) //assigns pointer to USB location
{
cflieCopter1 = new CCrazyflie(crRadio1, 5); //Assigns Crazyflie1 to Radio1 on Channel 5
cflieCopter2 = new CCrazyflie(crRadio1, 80); //Assigns Crazyflie2 to Radio1 on Channel 80
}
else
{
std::cerr << "Could not connect to dongle 1. Did you plug it in?" << std::endl;
exit(-1);
}
usleep(10000);
</pre>
</code>
</blockquote>
:3. Initialize Second CrazyRadio (repeat as necessary...)
<blockquote>
<code>
<pre>
crRadio2 = new CCrazyRadio(1); // dongle number
if( crRadio2->startRadio() )
{
cflieCopter3 = new CCrazyflie(crRadio2, 25); //Assigns Crazyflie3 to Radio2 on Channel 25
cflieCopter4 = new CCrazyflie(crRadio2, 45); //Assigns Crazyflie4 to Radio2 on Channel 45
}
else
{
std::cerr << "Could not connect to dongle 2. Did you plug it in?" << std::endl;
exit(-1);
}
usleep(10000);
</pre>
</code>
</blockquote>
:4. (OPTIONAL) Modify Radio Parameters
<blockquote>
<code>
<pre>
crRadio1->setARDTime(2000); //Sets Wait Time (in μs) between Packet Retries (**MUST BE IN INCREMENTS OF 250**)
crRadio1->setARC(0); //Sets Number of times Retries Packet Send
crRadio1->setPower(P_0DBM); //Sets Radio Power (See CCrazyRadio.h for allowed ENUM values)
</pre>
</code>
</blockquote>
:5. '''Always''' Delete Radio Pointers Before Ending Program
<blockquote>
<code>
<pre>
delete crRadio1;
delete crRadio2;
</pre>
</code>
</blockquote>
'''Note:''' If you don't delete the pointers then you need to unplug the Radio and plug it back into the USB!
=== Changing Radio Channel ===
Changing the Radio Channel is easy, all you need to do is call the function:
<blockquote>
<code>
<pre>
crRadio1->setChannel( cflieCopter1->radioChannel() ); //Sets Radio channel to whatever value cflieCopter1 was assigned (The input can be replaced with a constant if needed)
</pre>
</code>
</blockquote>
==== How does it work? ====
The low level implementation of the <code> setChannel </code> function looks like this:
<blockquote>
<code>
<pre>
void CCrazyRadio::setChannel(int nChannel) {
if( ALL_THE_DEBUG ) printf( "%s(nChannel:%d)\n", __FUNCTION__, nChannel );
this->writeControl(NULL, 0, 0x01, nChannel, 0);
}
</pre>
</code>
</blockquote>
Which is using a libusb command <code> writeControl </code> to find the specific USB address of the Radio and write a new Channel to that USB device. The specific values plugged into this function will need to be looked up if you plan on working at this level.
----
<center> [[Crazyflie Swarm]] | [[PC Client Software]] | [[Firmware]] </center>
7d9e637fb4a0ea1b02f8f813f9d76a884088f7cd
30
29
2016-07-09T20:01:53Z
Jnoronha
3
Removed mistaken file link
wikitext
text/x-wiki
The USB Radio Dongle acts as the bridge between the Client and the Firmware. It sends control setpoints generated from the Client to the Firmware controllers, as well as receives sensor data from the Firmware to the Client for logging.
== Modifying the Radio ==
The Radio functions can be found in the [[CCrazyRadio.cpp]] source file.
=== Radio Initialization ===
The following steps are how to Initialize a Radio. This code is currently run at the start of <code> main </code> in [[eris_vrpn.cpp]]. The process below can be extended to '''any number of Radios''' (currently 2 Radios shown)
:1. Create CrazyRadio Pointers and Crazyflie Pointers
<blockquote>
<code>
<pre>
CCrazyRadio *crRadio1 = 0;
CCrazyRadio *crRadio2 = 0;
CCrazyflie *cflieCopter1 = 0;
CCrazyflie *cflieCopter2 = 0;
CCrazyflie *cflieCopter3 = 0;
CCrazyflie *cflieCopter4 = 0;
</pre>
</code>
</blockquote>
'''Note:''' You must have a pointer for EACH Radio you want to initialize.
:2. Initialize First CrazyRadio
<blockquote>
<code>
<pre>
crRadio1 = new CCrazyRadio(0); // dongle number (starting at 0)
if( crRadio1->startRadio() ) //assigns pointer to USB location
{
cflieCopter1 = new CCrazyflie(crRadio1, 5); //Assigns Crazyflie1 to Radio1 on Channel 5
cflieCopter2 = new CCrazyflie(crRadio1, 80); //Assigns Crazyflie2 to Radio1 on Channel 80
}
else
{
std::cerr << "Could not connect to dongle 1. Did you plug it in?" << std::endl;
exit(-1);
}
usleep(10000);
</pre>
</code>
</blockquote>
:3. Initialize Second CrazyRadio (repeat as necessary...)
<blockquote>
<code>
<pre>
crRadio2 = new CCrazyRadio(1); // dongle number
if( crRadio2->startRadio() )
{
cflieCopter3 = new CCrazyflie(crRadio2, 25); //Assigns Crazyflie3 to Radio2 on Channel 25
cflieCopter4 = new CCrazyflie(crRadio2, 45); //Assigns Crazyflie4 to Radio2 on Channel 45
}
else
{
std::cerr << "Could not connect to dongle 2. Did you plug it in?" << std::endl;
exit(-1);
}
usleep(10000);
</pre>
</code>
</blockquote>
:4. (OPTIONAL) Modify Radio Parameters
<blockquote>
<code>
<pre>
crRadio1->setARDTime(2000); //Sets Wait Time (in μs) between Packet Retries (**MUST BE IN INCREMENTS OF 250**)
crRadio1->setARC(0); //Sets Number of times Retries Packet Send
crRadio1->setPower(P_0DBM); //Sets Radio Power (See CCrazyRadio.h for allowed ENUM values)
</pre>
</code>
</blockquote>
:5. '''Always''' Delete Radio Pointers Before Ending Program
<blockquote>
<code>
<pre>
delete crRadio1;
delete crRadio2;
</pre>
</code>
</blockquote>
'''Note:''' If you don't delete the pointers then you need to unplug the Radio and plug it back into the USB!
=== Changing Radio Channel ===
Changing the Radio Channel is easy, all you need to do is call the function:
<blockquote>
<code>
<pre>
crRadio1->setChannel( cflieCopter1->radioChannel() ); //Sets Radio channel to whatever value cflieCopter1 was assigned (The input can be replaced with a constant if needed)
</pre>
</code>
</blockquote>
==== How does it work? ====
The low level implementation of the <code> setChannel </code> function looks like this:
<blockquote>
<code>
<pre>
void CCrazyRadio::setChannel(int nChannel) {
if( ALL_THE_DEBUG ) printf( "%s(nChannel:%d)\n", __FUNCTION__, nChannel );
this->writeControl(NULL, 0, 0x01, nChannel, 0);
}
</pre>
</code>
</blockquote>
Which is using a libusb command <code> writeControl </code> to find the specific USB address of the Radio and write a new Channel to that USB device. The specific values plugged into this function will need to be looked up if you plan on working at this level.
----
<center> [[Crazyflie Swarm]] | [[PC Client Software]] | [[Firmware]] </center>
c575faf055d0eaad5a4d4ea8c445ea87d7daae43
31
30
2016-07-12T16:12:09Z
Jnoronha
3
Added 'how does it work' section to the radio init
wikitext
text/x-wiki
The USB Radio Dongle acts as the bridge between the Client and the Firmware. It sends control setpoints generated from the Client to the Firmware controllers, as well as receives sensor data from the Firmware to the Client for logging.
== Modifying the Radio ==
The Radio functions can be found in the [[CCrazyRadio.cpp]] source file.
=== Radio Initialization ===
The following steps are how to Initialize a Radio. This code is currently run at the start of <code> main </code> in [[eris_vrpn.cpp]]. The process below can be extended to '''any number of Radios''' (currently 2 Radios shown)
:1. Create CrazyRadio Pointers and Crazyflie Pointers
<blockquote>
<code>
<pre>
CCrazyRadio *crRadio1 = 0;
CCrazyRadio *crRadio2 = 0;
CCrazyflie *cflieCopter1 = 0;
CCrazyflie *cflieCopter2 = 0;
CCrazyflie *cflieCopter3 = 0;
CCrazyflie *cflieCopter4 = 0;
</pre>
</code>
</blockquote>
'''Note:''' You must have a pointer for EACH Radio you want to initialize.
:2. Initialize First CrazyRadio
<blockquote>
<code>
<pre>
crRadio1 = new CCrazyRadio(0); // dongle number (starting at 0)
if( crRadio1->startRadio() ) //assigns pointer to USB location
{
cflieCopter1 = new CCrazyflie(crRadio1, 5); //Assigns Crazyflie1 to Radio1 on Channel 5
cflieCopter2 = new CCrazyflie(crRadio1, 80); //Assigns Crazyflie2 to Radio1 on Channel 80
}
else
{
std::cerr << "Could not connect to dongle 1. Did you plug it in?" << std::endl;
exit(-1);
}
usleep(10000);
</pre>
</code>
</blockquote>
:3. Initialize Second CrazyRadio (repeat as necessary...)
<blockquote>
<code>
<pre>
crRadio2 = new CCrazyRadio(1); // dongle number
if( crRadio2->startRadio() )
{
cflieCopter3 = new CCrazyflie(crRadio2, 25); //Assigns Crazyflie3 to Radio2 on Channel 25
cflieCopter4 = new CCrazyflie(crRadio2, 45); //Assigns Crazyflie4 to Radio2 on Channel 45
}
else
{
std::cerr << "Could not connect to dongle 2. Did you plug it in?" << std::endl;
exit(-1);
}
usleep(10000);
</pre>
</code>
</blockquote>
:4. (OPTIONAL) Modify Radio Parameters
<blockquote>
<code>
<pre>
crRadio1->setARDTime(2000); //Sets Wait Time (in μs) between Packet Retries (**MUST BE IN INCREMENTS OF 250**)
crRadio1->setARC(0); //Sets Number of times Retries Packet Send
crRadio1->setPower(P_0DBM); //Sets Radio Power (See CCrazyRadio.h for allowed ENUM values)
</pre>
</code>
</blockquote>
:5. '''Always''' Delete Radio Pointers Before Ending Program
<blockquote>
<code>
<pre>
delete crRadio1;
delete crRadio2;
</pre>
</code>
</blockquote>
'''Note:''' If you don't delete the pointers then you need to unplug the Radio and plug it back into the USB!
====How does it work?====
The Radio initialization was originally only able to support a single Radio per computer and a single Crazyflie per Radio. This was a result of how the <code> openUSBDongle() </code> function was written.
=== Changing Radio Channel ===
Changing the Radio Channel is easy, all you need to do is call the function:
<blockquote>
<code>
<pre>
crRadio1->setChannel( cflieCopter1->radioChannel() ); //Sets Radio channel to whatever value cflieCopter1 was assigned (The input can be replaced with a constant if needed)
</pre>
</code>
</blockquote>
==== How does it work? ====
The low level implementation of the <code> setChannel </code> function looks like this:
<blockquote>
<code>
<pre>
void CCrazyRadio::setChannel(int nChannel) {
if( ALL_THE_DEBUG ) printf( "%s(nChannel:%d)\n", __FUNCTION__, nChannel );
this->writeControl(NULL, 0, 0x01, nChannel, 0);
}
</pre>
</code>
</blockquote>
Which is using a libusb command <code> writeControl </code> to find the specific USB address of the Radio and write a new Channel to that USB device. The specific values plugged into this function will need to be looked up if you plan on working at this level.
----
<center> [[Crazyflie Swarm]] | [[PC Client Software]] | [[Firmware]] </center>
f25af661ab0be75c83fe77c11d1b7bd9bb72fa17
49
31
2016-07-12T17:22:52Z
Jnoronha
3
Added images to radio init how does it work
wikitext
text/x-wiki
The USB Radio Dongle acts as the bridge between the Client and the Firmware. It sends control setpoints generated from the Client to the Firmware controllers, as well as receives sensor data from the Firmware to the Client for logging.
== Modifying the Radio ==
The Radio functions can be found in the [[CCrazyRadio.cpp]] source file.
=== Radio Initialization ===
The following steps are how to Initialize a Radio. This code is currently run at the start of <code> main </code> in [[eris_vrpn.cpp]]. The process below can be extended to '''any number of Radios''' (currently 2 Radios shown)
:1. Create CrazyRadio Pointers and Crazyflie Pointers
<blockquote>
<code>
<pre>
CCrazyRadio *crRadio1 = 0;
CCrazyRadio *crRadio2 = 0;
CCrazyflie *cflieCopter1 = 0;
CCrazyflie *cflieCopter2 = 0;
CCrazyflie *cflieCopter3 = 0;
CCrazyflie *cflieCopter4 = 0;
</pre>
</code>
</blockquote>
'''Note:''' You must have a pointer for EACH Radio you want to initialize.
:2. Initialize First CrazyRadio
<blockquote>
<code>
<pre>
crRadio1 = new CCrazyRadio(0); // dongle number (starting at 0)
if( crRadio1->startRadio() ) //assigns pointer to USB location
{
cflieCopter1 = new CCrazyflie(crRadio1, 5); //Assigns Crazyflie1 to Radio1 on Channel 5
cflieCopter2 = new CCrazyflie(crRadio1, 80); //Assigns Crazyflie2 to Radio1 on Channel 80
}
else
{
std::cerr << "Could not connect to dongle 1. Did you plug it in?" << std::endl;
exit(-1);
}
usleep(10000);
</pre>
</code>
</blockquote>
:3. Initialize Second CrazyRadio (repeat as necessary...)
<blockquote>
<code>
<pre>
crRadio2 = new CCrazyRadio(1); // dongle number
if( crRadio2->startRadio() )
{
cflieCopter3 = new CCrazyflie(crRadio2, 25); //Assigns Crazyflie3 to Radio2 on Channel 25
cflieCopter4 = new CCrazyflie(crRadio2, 45); //Assigns Crazyflie4 to Radio2 on Channel 45
}
else
{
std::cerr << "Could not connect to dongle 2. Did you plug it in?" << std::endl;
exit(-1);
}
usleep(10000);
</pre>
</code>
</blockquote>
:4. (OPTIONAL) Modify Radio Parameters
<blockquote>
<code>
<pre>
crRadio1->setARDTime(2000); //Sets Wait Time (in μs) between Packet Retries (**MUST BE IN INCREMENTS OF 250**)
crRadio1->setARC(0); //Sets Number of times Retries Packet Send
crRadio1->setPower(P_0DBM); //Sets Radio Power (See CCrazyRadio.h for allowed ENUM values)
</pre>
</code>
</blockquote>
:5. '''Always''' Delete Radio Pointers Before Ending Program
<blockquote>
<code>
<pre>
delete crRadio1;
delete crRadio2;
</pre>
</code>
</blockquote>
'''Note:''' If you don't delete the pointers then you need to unplug the Radio and plug it back into the USB!
====How does it work?====
The Radio initialization was originally only able to support a single Radio per computer and a single Crazyflie per Radio. This was a result of how the <code> openUSBDongle() </code> function was written.
Orignially the code worked as follows:
[[Image:RadioSelectionORIGINAL.png]]
The issue with this is that if you want to assign another Radio it will always point to the same USB address, thus the different Radio pointers <code> crRadio1 </code> and <code> crRadio2 </code> would point to the same Radio dongle. So we modified the <code> openUSBDongle() </code> to take in the number of Radios you want to start, and then initialize them as follows:
[[Image:RadioSelectionMULTIRADIO.png]]
=== Changing Radio Channel ===
Changing the Radio Channel is easy, all you need to do is call the function:
<blockquote>
<code>
<pre>
crRadio1->setChannel( cflieCopter1->radioChannel() ); //Sets Radio channel to whatever value cflieCopter1 was assigned (The input can be replaced with a constant if needed)
</pre>
</code>
</blockquote>
==== How does it work? ====
The low level implementation of the <code> setChannel </code> function looks like this:
<blockquote>
<code>
<pre>
void CCrazyRadio::setChannel(int nChannel) {
if( ALL_THE_DEBUG ) printf( "%s(nChannel:%d)\n", __FUNCTION__, nChannel );
this->writeControl(NULL, 0, 0x01, nChannel, 0);
}
</pre>
</code>
</blockquote>
Which is using a libusb command <code> writeControl </code> to find the specific USB address of the Radio and write a new Channel to that USB device. The specific values plugged into this function will need to be looked up if you plan on working at this level.
----
<center> [[Crazyflie Swarm]] | [[PC Client Software]] | [[Firmware]] </center>
33bdff400988c1f6b52dfc59d29343ece78f1e35
50
49
2016-07-12T17:23:37Z
Jnoronha
3
spelling mistake
wikitext
text/x-wiki
The USB Radio Dongle acts as the bridge between the Client and the Firmware. It sends control setpoints generated from the Client to the Firmware controllers, as well as receives sensor data from the Firmware to the Client for logging.
== Modifying the Radio ==
The Radio functions can be found in the [[CCrazyRadio.cpp]] source file.
=== Radio Initialization ===
The following steps are how to Initialize a Radio. This code is currently run at the start of <code> main </code> in [[eris_vrpn.cpp]]. The process below can be extended to '''any number of Radios''' (currently 2 Radios shown)
:1. Create CrazyRadio Pointers and Crazyflie Pointers
<blockquote>
<code>
<pre>
CCrazyRadio *crRadio1 = 0;
CCrazyRadio *crRadio2 = 0;
CCrazyflie *cflieCopter1 = 0;
CCrazyflie *cflieCopter2 = 0;
CCrazyflie *cflieCopter3 = 0;
CCrazyflie *cflieCopter4 = 0;
</pre>
</code>
</blockquote>
'''Note:''' You must have a pointer for EACH Radio you want to initialize.
:2. Initialize First CrazyRadio
<blockquote>
<code>
<pre>
crRadio1 = new CCrazyRadio(0); // dongle number (starting at 0)
if( crRadio1->startRadio() ) //assigns pointer to USB location
{
cflieCopter1 = new CCrazyflie(crRadio1, 5); //Assigns Crazyflie1 to Radio1 on Channel 5
cflieCopter2 = new CCrazyflie(crRadio1, 80); //Assigns Crazyflie2 to Radio1 on Channel 80
}
else
{
std::cerr << "Could not connect to dongle 1. Did you plug it in?" << std::endl;
exit(-1);
}
usleep(10000);
</pre>
</code>
</blockquote>
:3. Initialize Second CrazyRadio (repeat as necessary...)
<blockquote>
<code>
<pre>
crRadio2 = new CCrazyRadio(1); // dongle number
if( crRadio2->startRadio() )
{
cflieCopter3 = new CCrazyflie(crRadio2, 25); //Assigns Crazyflie3 to Radio2 on Channel 25
cflieCopter4 = new CCrazyflie(crRadio2, 45); //Assigns Crazyflie4 to Radio2 on Channel 45
}
else
{
std::cerr << "Could not connect to dongle 2. Did you plug it in?" << std::endl;
exit(-1);
}
usleep(10000);
</pre>
</code>
</blockquote>
:4. (OPTIONAL) Modify Radio Parameters
<blockquote>
<code>
<pre>
crRadio1->setARDTime(2000); //Sets Wait Time (in μs) between Packet Retries (**MUST BE IN INCREMENTS OF 250**)
crRadio1->setARC(0); //Sets Number of times Retries Packet Send
crRadio1->setPower(P_0DBM); //Sets Radio Power (See CCrazyRadio.h for allowed ENUM values)
</pre>
</code>
</blockquote>
:5. '''Always''' Delete Radio Pointers Before Ending Program
<blockquote>
<code>
<pre>
delete crRadio1;
delete crRadio2;
</pre>
</code>
</blockquote>
'''Note:''' If you don't delete the pointers then you need to unplug the Radio and plug it back into the USB!
====How does it work?====
The Radio initialization was originally only able to support a single Radio per computer and a single Crazyflie per Radio. This was a result of how the <code> openUSBDongle() </code> function was written.
Originally the code worked as follows:
[[Image:RadioSelectionORIGINAL.png]]
The issue with this is that if you want to assign another Radio it will always point to the same USB address, thus the different Radio pointers <code> crRadio1 </code> and <code> crRadio2 </code> would point to the same Radio dongle. So we modified the <code> openUSBDongle() </code> to take in the number of Radios you want to start, and then initialize them as follows:
[[Image:RadioSelectionMULTIRADIO.png]]
=== Changing Radio Channel ===
Changing the Radio Channel is easy, all you need to do is call the function:
<blockquote>
<code>
<pre>
crRadio1->setChannel( cflieCopter1->radioChannel() ); //Sets Radio channel to whatever value cflieCopter1 was assigned (The input can be replaced with a constant if needed)
</pre>
</code>
</blockquote>
==== How does it work? ====
The low level implementation of the <code> setChannel </code> function looks like this:
<blockquote>
<code>
<pre>
void CCrazyRadio::setChannel(int nChannel) {
if( ALL_THE_DEBUG ) printf( "%s(nChannel:%d)\n", __FUNCTION__, nChannel );
this->writeControl(NULL, 0, 0x01, nChannel, 0);
}
</pre>
</code>
</blockquote>
Which is using a libusb command <code> writeControl </code> to find the specific USB address of the Radio and write a new Channel to that USB device. The specific values plugged into this function will need to be looked up if you plan on working at this level.
----
<center> [[Crazyflie Swarm]] | [[PC Client Software]] | [[Firmware]] </center>
f0a4c33169fcb648ee228c0191a98f357f441a58
Eris vrpn.cpp
0
7
27
2016-07-09T18:54:04Z
Jnoronha
3
Set up framework for codebase
wikitext
text/x-wiki
This is the C code for the mainloop of the Crazyflie Swarm Platform (as of 7/9/2016).
'''Please update this with new changes.'''
<blockquote>
<code>
<pre>
***INSERT CODE***
</pre>
</code>
</blockquote>
2161e1e4b01b33b97264c13aa280bbb3e3d38963
File:RadioSelectionMULTIRADIO.png
6
8
32
2016-07-12T16:12:51Z
Jnoronha
3
Flow chart of Multi-Radio Initialization
wikitext
text/x-wiki
Flow chart of Multi-Radio Initialization
28320075626fd572c74f87c4d1ed33860d2d5eef
File:RadioSelectionORIGINAL.png
6
9
33
2016-07-12T16:14:23Z
Jnoronha
3
Flow chart of the Original Radio Initialization process.
wikitext
text/x-wiki
Flow chart of the Original Radio Initialization process.
ed17336d08641cf8267b2c2734173df29fdec7ef
File:Keyboard Input.png
6
10
34
2016-07-12T16:15:02Z
Jnoronha
3
Flow chart of the Keyboard Input sub-routine
wikitext
text/x-wiki
Flow chart of the Keyboard Input sub-routine
b4ea53f4359ccfe92050fb077a2e3d6e1d2f2a08
File:LandingMode.png
6
11
35
2016-07-12T16:16:07Z
Jnoronha
3
Flow chart of the LANDING flight mode.
wikitext
text/x-wiki
Flow chart of the LANDING flight mode.
7f466e2a065d69f2e64d885d32a606671d13161a
File:VRPNGO.png
6
12
36
2016-07-12T16:17:12Z
Jnoronha
3
Flow Chart of the platform's main loop.
wikitext
text/x-wiki
Flow Chart of the platform's main loop.
346a1f38528078d81a904aa3bb5c70886fe93576
File:YawSync.png
6
13
37
2016-07-12T16:18:29Z
Jnoronha
3
Flow Chart of the Yaw synchronization sub-routine.
wikitext
text/x-wiki
Flow Chart of the Yaw synchronization sub-routine.
22c53518ef747216c95cf3ba580da0e2a7a96706
File:VRPN INIT.png
6
14
38
2016-07-12T16:19:27Z
Jnoronha
3
Flow chart of the Connection initialization to VRPN.
wikitext
text/x-wiki
Flow chart of the Connection initialization to VRPN.
43e8b620aa2e802eb203b7ae4a731747212fdee6
File:RequestLogDataPacketEx.png
6
15
39
2016-07-12T16:20:30Z
Jnoronha
3
Communications packet Diagram example of Logging Data sent from the Crazyflie to the Client
wikitext
text/x-wiki
Communications packet Diagram example of Logging Data sent from the Crazyflie to the Client
b88a15e61391ddb1dbb91d2a45e15f54336c2aef
File:FirmwareOnlyPIDArchitecture.png
6
16
40
2016-07-12T16:22:56Z
Jnoronha
3
Block diagram of the Angular Rate and Angular Position PID's located on the Crazyflie Firmware.
wikitext
text/x-wiki
Block diagram of the Angular Rate and Angular Position PID's located on the Crazyflie Firmware.
34061a4dd79f6ee4d1cab6ebf296bc85d51ee2ed
File:CompletePIDArchitectureFigure.png
6
17
41
2016-07-12T16:24:08Z
Jnoronha
3
Block diagram of the entire Platform's PID architecture. (4 PID's located on the Client, and 5 PID's located on the Firmware)
wikitext
text/x-wiki
Block diagram of the entire Platform's PID architecture. (4 PID's located on the Client, and 5 PID's located on the Firmware)
1e6d7fd474efcb599846242b725db9ba3accac0e
File:Camera9Figure.jpg
6
18
42
2016-07-12T16:26:27Z
Jnoronha
3
Photo of the OptiTrack motion capture camera system. (Cameras 7, 8, 9)
wikitext
text/x-wiki
Photo of the OptiTrack motion capture camera system. (Cameras 7, 8, 9)
f36c3fa881fcdb5c008d77084b5b06b6bcac5e5a
File:MultiRadioMultiCrazyflie.jpg
6
19
43
2016-07-12T16:29:01Z
Jnoronha
3
High level architecture of the Multi-Radio Multi-Crazyflie (single Crazyflie per Radio) configuration.
wikitext
text/x-wiki
High level architecture of the Multi-Radio Multi-Crazyflie (single Crazyflie per Radio) configuration.
cb3a74d6f8a12688c646e044420ee68537ef811a
File:SingleRadioMultiCrazyflie.jpg
6
20
44
2016-07-12T16:32:01Z
Jnoronha
3
High level architecture of the Single-Radio Multi-Crazyflie platform configuration.
wikitext
text/x-wiki
High level architecture of the Single-Radio Multi-Crazyflie platform configuration.
d4dcc2417fe0c802dacc05a3c175a13af66a041f
File:3spheres.png
6
21
45
2016-07-12T16:35:47Z
Jnoronha
3
Figure of the Intersection of 3 Spheres for solving Trilateration problem.
(Source: https://en.wikipedia.org/wiki/Trilateration#/media/File:3spheres.svg)
wikitext
text/x-wiki
Figure of the Intersection of 3 Spheres for solving Trilateration problem.
(Source: https://en.wikipedia.org/wiki/Trilateration#/media/File:3spheres.svg)
7df4cc3e23bf2f9934d34d490013a4345761e3b6
File:DefaultCrazyflieGUIMainScreen.JPG
6
22
46
2016-07-12T16:37:02Z
Jnoronha
3
Screenshot of the Crazyflie GUI running on the Bitcraze Virtual Machine.
wikitext
text/x-wiki
Screenshot of the Crazyflie GUI running on the Bitcraze Virtual Machine.
3f0833d93b7d61b6c60ffcc76ef3f0fa0ec9401e
File:DefaultCrazyflieGUIBootloader.JPG
6
23
47
2016-07-12T16:38:02Z
Jnoronha
3
Screenshot of the Crazyflie Bootloader User Interface.
wikitext
text/x-wiki
Screenshot of the Crazyflie Bootloader User Interface.
9414da3f61ffe8574ac5f9b79654f2f8294c89b3
File:RadioSelectionOldToNew.png
6
24
51
2016-07-12T17:24:24Z
Jnoronha
3
Flow chart comparison of the Original Radio init to the Modified Radio init.
wikitext
text/x-wiki
Flow chart comparison of the Original Radio init to the Modified Radio init.
11b3c83bbf7c657b47394fca92ebf32dd52808f1
52
51
2016-07-12T17:31:28Z
Jnoronha
3
uploaded a new version of "[[Image:RadioSelectionOldToNew.png]]": Flow Chart comparison of the Original Radio init to the new Multi-Radio Init.
wikitext
text/x-wiki
Flow chart comparison of the Original Radio init to the Modified Radio init.
11b3c83bbf7c657b47394fca92ebf32dd52808f1
USB Radio
0
6
53
50
2016-07-12T17:33:32Z
Jnoronha
3
Combined Radio Init images into one OldToNew image
wikitext
text/x-wiki
The USB Radio Dongle acts as the bridge between the Client and the Firmware. It sends control setpoints generated from the Client to the Firmware controllers, as well as receives sensor data from the Firmware to the Client for logging.
== Modifying the Radio ==
The Radio functions can be found in the [[CCrazyRadio.cpp]] source file.
=== Radio Initialization ===
The following steps are how to Initialize a Radio. This code is currently run at the start of <code> main </code> in [[eris_vrpn.cpp]]. The process below can be extended to '''any number of Radios''' (currently 2 Radios shown)
:1. Create CrazyRadio Pointers and Crazyflie Pointers
<blockquote>
<code>
<pre>
CCrazyRadio *crRadio1 = 0;
CCrazyRadio *crRadio2 = 0;
CCrazyflie *cflieCopter1 = 0;
CCrazyflie *cflieCopter2 = 0;
CCrazyflie *cflieCopter3 = 0;
CCrazyflie *cflieCopter4 = 0;
</pre>
</code>
</blockquote>
'''Note:''' You must have a pointer for EACH Radio you want to initialize.
:2. Initialize First CrazyRadio
<blockquote>
<code>
<pre>
crRadio1 = new CCrazyRadio(0); // dongle number (starting at 0)
if( crRadio1->startRadio() ) //assigns pointer to USB location
{
cflieCopter1 = new CCrazyflie(crRadio1, 5); //Assigns Crazyflie1 to Radio1 on Channel 5
cflieCopter2 = new CCrazyflie(crRadio1, 80); //Assigns Crazyflie2 to Radio1 on Channel 80
}
else
{
std::cerr << "Could not connect to dongle 1. Did you plug it in?" << std::endl;
exit(-1);
}
usleep(10000);
</pre>
</code>
</blockquote>
:3. Initialize Second CrazyRadio (repeat as necessary...)
<blockquote>
<code>
<pre>
crRadio2 = new CCrazyRadio(1); // dongle number
if( crRadio2->startRadio() )
{
cflieCopter3 = new CCrazyflie(crRadio2, 25); //Assigns Crazyflie3 to Radio2 on Channel 25
cflieCopter4 = new CCrazyflie(crRadio2, 45); //Assigns Crazyflie4 to Radio2 on Channel 45
}
else
{
std::cerr << "Could not connect to dongle 2. Did you plug it in?" << std::endl;
exit(-1);
}
usleep(10000);
</pre>
</code>
</blockquote>
:4. (OPTIONAL) Modify Radio Parameters
<blockquote>
<code>
<pre>
crRadio1->setARDTime(2000); //Sets Wait Time (in μs) between Packet Retries (**MUST BE IN INCREMENTS OF 250**)
crRadio1->setARC(0); //Sets Number of times Retries Packet Send
crRadio1->setPower(P_0DBM); //Sets Radio Power (See CCrazyRadio.h for allowed ENUM values)
</pre>
</code>
</blockquote>
:5. '''Always''' Delete Radio Pointers Before Ending Program
<blockquote>
<code>
<pre>
delete crRadio1;
delete crRadio2;
</pre>
</code>
</blockquote>
'''Note:''' If you don't delete the pointers then you need to unplug the Radio and plug it back into the USB!
====How does it work?====
The Radio initialization was originally only able to support a single Radio per computer and a single Crazyflie per Radio. This was a result of how the <code> openUSBDongle() </code> function was written.
Originally the code worked as follows:
[[Image:RadioSelectionOldToNew.png]]
The issue with this is that if you want to assign another Radio it will always point to the same USB address, thus the different Radio pointers <code> crRadio1 </code> and <code> crRadio2 </code> would point to the same Radio dongle. So we modified the <code> openUSBDongle() </code> to take in the number of Radios you want to start, and then initialize them with a loop.
=== Changing Radio Channel ===
Changing the Radio Channel is easy, all you need to do is call the function:
<blockquote>
<code>
<pre>
crRadio1->setChannel( cflieCopter1->radioChannel() ); //Sets Radio channel to whatever value cflieCopter1 was assigned (The input can be replaced with a constant if needed)
</pre>
</code>
</blockquote>
==== How does it work? ====
The low level implementation of the <code> setChannel </code> function looks like this:
<blockquote>
<code>
<pre>
void CCrazyRadio::setChannel(int nChannel) {
if( ALL_THE_DEBUG ) printf( "%s(nChannel:%d)\n", __FUNCTION__, nChannel );
this->writeControl(NULL, 0, 0x01, nChannel, 0);
}
</pre>
</code>
</blockquote>
Which is using a libusb command <code> writeControl </code> to find the specific USB address of the Radio and write a new Channel to that USB device. The specific values plugged into this function will need to be looked up if you plan on working at this level.
----
<center> [[Crazyflie Swarm]] | [[PC Client Software]] | [[Firmware]] </center>
7b6c72950a94a2b240cae0de4382df51d7fffc6d
57
53
2016-07-12T18:08:31Z
Jnoronha
3
Updated Navigation Bar
wikitext
text/x-wiki
The USB Radio Dongle acts as the bridge between the Client and the Firmware. It sends control setpoints generated from the Client to the Firmware controllers, as well as receives sensor data from the Firmware to the Client for logging.
== Modifying the Radio ==
The Radio functions can be found in the [[CCrazyRadio.cpp]] source file.
=== Radio Initialization ===
The following steps are how to Initialize a Radio. This code is currently run at the start of <code> main </code> in [[eris_vrpn.cpp]]. The process below can be extended to '''any number of Radios''' (currently 2 Radios shown)
:1. Create CrazyRadio Pointers and Crazyflie Pointers
<blockquote>
<code>
<pre>
CCrazyRadio *crRadio1 = 0;
CCrazyRadio *crRadio2 = 0;
CCrazyflie *cflieCopter1 = 0;
CCrazyflie *cflieCopter2 = 0;
CCrazyflie *cflieCopter3 = 0;
CCrazyflie *cflieCopter4 = 0;
</pre>
</code>
</blockquote>
'''Note:''' You must have a pointer for EACH Radio you want to initialize.
:2. Initialize First CrazyRadio
<blockquote>
<code>
<pre>
crRadio1 = new CCrazyRadio(0); // dongle number (starting at 0)
if( crRadio1->startRadio() ) //assigns pointer to USB location
{
cflieCopter1 = new CCrazyflie(crRadio1, 5); //Assigns Crazyflie1 to Radio1 on Channel 5
cflieCopter2 = new CCrazyflie(crRadio1, 80); //Assigns Crazyflie2 to Radio1 on Channel 80
}
else
{
std::cerr << "Could not connect to dongle 1. Did you plug it in?" << std::endl;
exit(-1);
}
usleep(10000);
</pre>
</code>
</blockquote>
:3. Initialize Second CrazyRadio (repeat as necessary...)
<blockquote>
<code>
<pre>
crRadio2 = new CCrazyRadio(1); // dongle number
if( crRadio2->startRadio() )
{
cflieCopter3 = new CCrazyflie(crRadio2, 25); //Assigns Crazyflie3 to Radio2 on Channel 25
cflieCopter4 = new CCrazyflie(crRadio2, 45); //Assigns Crazyflie4 to Radio2 on Channel 45
}
else
{
std::cerr << "Could not connect to dongle 2. Did you plug it in?" << std::endl;
exit(-1);
}
usleep(10000);
</pre>
</code>
</blockquote>
:4. (OPTIONAL) Modify Radio Parameters
<blockquote>
<code>
<pre>
crRadio1->setARDTime(2000); //Sets Wait Time (in μs) between Packet Retries (**MUST BE IN INCREMENTS OF 250**)
crRadio1->setARC(0); //Sets Number of times Retries Packet Send
crRadio1->setPower(P_0DBM); //Sets Radio Power (See CCrazyRadio.h for allowed ENUM values)
</pre>
</code>
</blockquote>
:5. '''Always''' Delete Radio Pointers Before Ending Program
<blockquote>
<code>
<pre>
delete crRadio1;
delete crRadio2;
</pre>
</code>
</blockquote>
'''Note:''' If you don't delete the pointers then you need to unplug the Radio and plug it back into the USB!
====How does it work?====
The Radio initialization was originally only able to support a single Radio per computer and a single Crazyflie per Radio. This was a result of how the <code> openUSBDongle() </code> function was written.
Originally the code worked as follows:
[[Image:RadioSelectionOldToNew.png]]
The issue with this is that if you want to assign another Radio it will always point to the same USB address, thus the different Radio pointers <code> crRadio1 </code> and <code> crRadio2 </code> would point to the same Radio dongle. So we modified the <code> openUSBDongle() </code> to take in the number of Radios you want to start, and then initialize them with a loop.
=== Changing Radio Channel ===
Changing the Radio Channel is easy, all you need to do is call the function:
<blockquote>
<code>
<pre>
crRadio1->setChannel( cflieCopter1->radioChannel() ); //Sets Radio channel to whatever value cflieCopter1 was assigned (The input can be replaced with a constant if needed)
</pre>
</code>
</blockquote>
==== How does it work? ====
The low level implementation of the <code> setChannel </code> function looks like this:
<blockquote>
<code>
<pre>
void CCrazyRadio::setChannel(int nChannel) {
if( ALL_THE_DEBUG ) printf( "%s(nChannel:%d)\n", __FUNCTION__, nChannel );
this->writeControl(NULL, 0, 0x01, nChannel, 0);
}
</pre>
</code>
</blockquote>
Which is using a libusb command <code> writeControl </code> to find the specific USB address of the Radio and write a new Channel to that USB device. The specific values plugged into this function will need to be looked up if you plan on working at this level.
----
<center> [[Crazyflie Swarm]] | [[PC Client Software]] | [[USB Radio]] | [[Firmware]] </center>
254174b43e84ee47e683bae4077a18b76f0066c3
PC Client Software
0
25
54
2016-07-12T17:54:24Z
Jnoronha
3
Added the introduction and section headers
wikitext
text/x-wiki
The PC Client software comes in many forms. The out-of-the-box Client is written in Python and has a Graphical User Interface (GUI). The GUI is well suited for beginners, but can only support a single Radio and a single Crazyflie at a time. The easiest way to start out is with the [https://wiki.bitcraze.io/projects:virtualmachine:index Bitcraze Virtual Machine (VM)], which comes with all the files and dependencies pre-installed and can run on any computer (Windows, Mac, Linux, etc.).
For more advanced users who want to use the swarm capabilities of our platform will have to use the Client we developed in C and C++.
==Bitcraze VM==
==Swarm Client==
Our Client is programmed in C and C++.
530bc8258eea8a9b81d6efac1d007f30494547b6
55
54
2016-07-12T18:05:29Z
Jnoronha
3
Added VM disclaimer
wikitext
text/x-wiki
The PC Client software comes in many forms. The out-of-the-box Client is written in Python and has a Graphical User Interface (GUI). The GUI is well suited for beginners, but can only support a single Radio and a single Crazyflie at a time. The easiest way to start out is with the [https://wiki.bitcraze.io/projects:virtualmachine:index Bitcraze Virtual Machine (VM)], which comes with all the files and dependencies pre-installed and can run on any computer (Windows, Mac, Linux, etc.).
For more advanced users who want to use the swarm capabilities of our platform will have to use the Client we developed in C and C++.
==[https://wiki.bitcraze.io/projects:virtualmachine:index Bitcraze VM]==
('''Note:''' The VM is updated frequently so the information below may be different than the current VM)
==Swarm Client==
Our Client is programmed in C and C++.
2b5dbf398a114e35b2e2e34cf65a31cfde348906
56
55
2016-07-12T18:07:38Z
Jnoronha
3
Added navigation bar
wikitext
text/x-wiki
The PC Client software comes in many forms. The out-of-the-box Client is written in Python and has a Graphical User Interface (GUI). The GUI is well suited for beginners, but can only support a single Radio and a single Crazyflie at a time. The easiest way to start out is with the [https://wiki.bitcraze.io/projects:virtualmachine:index Bitcraze Virtual Machine (VM)], which comes with all the files and dependencies pre-installed and can run on any computer (Windows, Mac, Linux, etc.).
For more advanced users who want to use the swarm capabilities of our platform will have to use the Client we developed in C and C++.
==[https://wiki.bitcraze.io/projects:virtualmachine:index Bitcraze VM]==
('''Note:''' The VM is updated frequently so the information below may be different than the current VM)
==Swarm Client==
Our Client is programmed in C and C++.
----
<center> [[Crazyflie Swarm]] | [[PC Client Software]] | [[USB Radio]] | [[Firmware]] </center>
0c6d9b6e4a3abe51543b6ba351938c1128474904
59
56
2016-07-12T19:57:06Z
Jnoronha
3
Added VM tutorials from Bitcraze Wiki
wikitext
text/x-wiki
The PC Client software comes in many forms. The out-of-the-box Client is written in Python and has a Graphical User Interface (GUI). The GUI is well suited for beginners, but can only support a single Radio and a single Crazyflie at a time. The easiest way to start out is with the [https://wiki.bitcraze.io/projects:virtualmachine:index Bitcraze Virtual Machine (VM)], which comes with all the files and dependencies pre-installed and can run on any computer (Windows, Mac, Linux, etc.).
For more advanced users who want to use the swarm capabilities of our platform will have to use the Client we developed in C and C++.
==[https://wiki.bitcraze.io/projects:virtualmachine:index Bitcraze VM]==
('''Note:''' The VM is updated frequently so the information below may be different than the current VM)
The Bitcraze wiki has a tutorial on [https://wiki.bitcraze.io/projects:virtualmachine:tutorials:vmware-win7 installing the VM]. Along with another tutorial on how to get started [https://www.bitcraze.io/getting-started-with-development/ using the VM].
These are both very simple starting guides that will help you become familiar with the VM.
==Swarm Client==
The swarm Client is a re-creation of the Original Client but programmed in C and C++.
----
<center> [[Crazyflie Swarm]] | [[PC Client Software]] | [[USB Radio]] | [[Firmware]] </center>
eaca70cba21fd4985fd91bf4af6e228772d7929a
79
59
2016-07-18T20:23:23Z
Jnoronha
3
Added intro to VM Client
wikitext
text/x-wiki
The PC Client software comes in many forms. The out-of-the-box Client is written in Python and has a Graphical User Interface (GUI). The GUI is well suited for beginners, but can only support a single Radio and a single Crazyflie at a time. The easiest way to start out is with the [https://wiki.bitcraze.io/projects:virtualmachine:index Bitcraze Virtual Machine (VM)], which comes with all the files and dependencies pre-installed and can run on any computer (Windows, Mac, Linux, etc.).
For more advanced users who want to use the swarm capabilities of our platform will have to use the [[#Swarm Client|Swarm Client]] we developed in C and C++.
==[https://wiki.bitcraze.io/projects:virtualmachine:index Bitcraze VM]==
('''Note:''' The VM is updated frequently so the information below may be different than the current VM)
The Bitcraze wiki has a tutorial on [https://wiki.bitcraze.io/projects:virtualmachine:tutorials:vmware-win7 installing the VM]. Along with another tutorial on how to get started [https://www.bitcraze.io/getting-started-with-development/ using the VM].
These are both very simple starting guides that will help you become familiar with the VM.
===Crazyflie Client GUI===
On the VM you can find the Crazyflie Client Graphical User Interface (GUI). To run the Client you want to open a terminal and navigate to <code>projects/''''FIND PATH''''</code> and then run the command <code>sudo ./bin/cfclient</code>
(Alternatively, you can use the desktop to navigate to the folder and open a terminal there)
Once you do that you should see something similar to this:
[[Image:DefaultCrazyflieGUIMainScreen.JPG|500px]]
This is the main screen of the Client GUI and there are many tabs and features that you can access directly from this screen.
The most important parts of this screen are the following:
#Connect Button
#Bootloader (Crazyflie Drop Down -> Bootloader)
#Plotter Tab
#Log Blocks Tab
#Parameters Tab
==Swarm Client==
The swarm Client is a re-creation of the Original Client but programmed in C and C++.
----
<center> [[Crazyflie Swarm]] | [[PC Client Software]] | [[USB Radio]] | [[Firmware]] </center>
c30dbe4f25e7fe2b2268cb310ae64c5990e28b86
80
79
2016-07-18T20:34:12Z
Jnoronha
3
Added connect image
wikitext
text/x-wiki
The PC Client software comes in many forms. The out-of-the-box Client is written in Python and has a Graphical User Interface (GUI). The GUI is well suited for beginners, but can only support a single Radio and a single Crazyflie at a time. The easiest way to start out is with the [https://wiki.bitcraze.io/projects:virtualmachine:index Bitcraze Virtual Machine (VM)], which comes with all the files and dependencies pre-installed and can run on any computer (Windows, Mac, Linux, etc.).
For more advanced users who want to use the swarm capabilities of our platform will have to use the [[#Swarm Client|Swarm Client]] we developed in C and C++.
==[https://wiki.bitcraze.io/projects:virtualmachine:index Bitcraze VM]==
('''Note:''' The VM is updated frequently so the information below may be different than the current VM)
The Bitcraze wiki has a tutorial on [https://wiki.bitcraze.io/projects:virtualmachine:tutorials:vmware-win7 installing the VM]. Along with another tutorial on how to get started [https://www.bitcraze.io/getting-started-with-development/ using the VM].
These are both very simple starting guides that will help you become familiar with the VM.
===Crazyflie Client GUI===
On the VM you can find the Crazyflie Client Graphical User Interface (GUI). To run the Client you want to open a terminal and navigate to <code>projects/''''FIND PATH''''</code> and then run the command <code>sudo ./bin/cfclient</code>
(Alternatively, you can use the desktop to navigate to the folder and open a terminal there)
Once you do that you should see something similar to this:
[[Image:DefaultCrazyflieGUIMainScreen.JPG|500px]]
This is the main screen of the Client GUI and there are many tabs and features that you can access directly from this screen.
The most important parts of this screen are the following:
#Connect Button
#Bootloader (Crazyflie Drop Down -> Bootloader)
#Plotter Tab
#Log Blocks Tab
#Parameters Tab
====Connect Button====
This is where you will scan for Crazyflies that are powered ON. All Crazyflies not already connected will show up in the popup
[[Image:DefaultCrazyflieGUIConnectScreen.JPG|400px]]
So we can see here that we got a return on Radio 0, from a Crazyflie on Channel 45 and a data rate of 2Mbps.
==Swarm Client==
The swarm Client is a re-creation of the Original Client but programmed in C and C++.
----
<center> [[Crazyflie Swarm]] | [[PC Client Software]] | [[USB Radio]] | [[Firmware]] </center>
955331e0e910528dd5669920254e1720f277d3b4
81
80
2016-07-19T02:48:09Z
Jnoronha
3
Added Bootloader
wikitext
text/x-wiki
The PC Client software comes in many forms. The out-of-the-box Client is written in Python and has a Graphical User Interface (GUI). The GUI is well suited for beginners, but can only support a single Radio and a single Crazyflie at a time. The easiest way to start out is with the [https://wiki.bitcraze.io/projects:virtualmachine:index Bitcraze Virtual Machine (VM)], which comes with all the files and dependencies pre-installed and can run on any computer (Windows, Mac, Linux, etc.).
For more advanced users who want to use the swarm capabilities of our platform will have to use the [[#Swarm Client|Swarm Client]] we developed in C and C++.
==[https://wiki.bitcraze.io/projects:virtualmachine:index Bitcraze VM]==
('''Note:''' The VM is updated frequently so the information below may be different than the current VM)
The Bitcraze wiki has a tutorial on [https://wiki.bitcraze.io/projects:virtualmachine:tutorials:vmware-win7 installing the VM]. Along with another tutorial on how to get started [https://www.bitcraze.io/getting-started-with-development/ using the VM].
These are both very simple starting guides that will help you become familiar with the VM.
===Crazyflie Client GUI===
On the VM you can find the Crazyflie Client Graphical User Interface (GUI). To run the Client you want to open a terminal and navigate to <code>projects/''''FIND PATH''''</code> and then run the command <code>sudo ./bin/cfclient</code>
(Alternatively, you can use the desktop to navigate to the folder and open a terminal there)
Once you do that you should see something similar to this:
[[Image:DefaultCrazyflieGUIMainScreen.JPG|500px]]
This is the main screen of the Client GUI and there are many tabs and features that you can access directly from this screen.
The most important parts of this screen are the following:
#Connect Button
#Bootloader (Crazyflie Drop Down -> Bootloader)
#Plotter Tab
#Log Blocks Tab
#Parameters Tab
====Connect Button====
This is where you will scan for Crazyflies that are powered ON. All Crazyflies not already connected will show up in the popup
[[Image:DefaultCrazyflieGUIConnectScreen.JPG|400px]]
We get a return that says <code>radio://0/45/2M</code>, this line is the identifier string of the Crazyflie we are trying to connect to.
What this is saying is that we got a return from a Radio (Radio 0 specifically), from a Crazyflie on Channel 45 using a data rate of 2Mbps.
====Bootloader====
This where you can install new Firmware to the Crazyflie.
[[Image:DefaultCrazyflieGUIBootloader.JPG|500px]]
The first thing you'll need to update is to build the Firmware version you want into a .bin file. You can do this by just running the <code>make</code> command in terminal while located inside the Firmware directory you have modified.
==Swarm Client==
The swarm Client is a re-creation of the Original Client but programmed in C and C++.
----
<center> [[Crazyflie Swarm]] | [[PC Client Software]] | [[USB Radio]] | [[Firmware]] </center>
a1a55e7bd9265d48c710eb3b5a50ca86c7b6e924
82
81
2016-07-19T03:14:24Z
Jnoronha
3
Added how to flash firmware
wikitext
text/x-wiki
The PC Client software comes in many forms. The out-of-the-box Client is written in Python and has a Graphical User Interface (GUI). The GUI is well suited for beginners, but can only support a single Radio and a single Crazyflie at a time. The easiest way to start out is with the [https://wiki.bitcraze.io/projects:virtualmachine:index Bitcraze Virtual Machine (VM)], which comes with all the files and dependencies pre-installed and can run on any computer (Windows, Mac, Linux, etc.).
For more advanced users who want to use the swarm capabilities of our platform will have to use the [[#Swarm Client|Swarm Client]] we developed in C and C++.
==[https://wiki.bitcraze.io/projects:virtualmachine:index Bitcraze VM]==
('''Note:''' The VM is updated frequently so the information below may be different than the current VM)
The Bitcraze wiki has a tutorial on [https://wiki.bitcraze.io/projects:virtualmachine:tutorials:vmware-win7 installing the VM]. Along with another tutorial on how to get started [https://www.bitcraze.io/getting-started-with-development/ using the VM].
These are both very simple starting guides that will help you become familiar with the VM.
===Crazyflie Client GUI===
On the VM you can find the Crazyflie Client Graphical User Interface (GUI). To run the Client you want to open a terminal and navigate to <code>projects/''''FIND PATH''''</code> and then run the command <code>sudo ./bin/cfclient</code>
(Alternatively, you can use the desktop to navigate to the folder and open a terminal there)
Once you do that you should see something similar to this:
[[Image:DefaultCrazyflieGUIMainScreen.JPG|500px]]
This is the main screen of the Client GUI and there are many tabs and features that you can access directly from this screen.
The most important parts of this screen are the following:
#Connect Button
#Bootloader (Crazyflie Drop Down -> Bootloader)
#Plotter Tab
#Log Blocks Tab
#Parameters Tab
====Connect Button====
This is where you will scan for Crazyflies that are powered ON. All Crazyflies not already connected will show up in the popup
[[Image:DefaultCrazyflieGUIConnectScreen.JPG|400px]]
We get a return that says <code>radio://0/45/2M</code>, this line is the identifier string of the Crazyflie we are trying to connect to.
What this is saying is that we got a return from a Radio (Radio 0 specifically), from a Crazyflie on Channel 45 using a data rate of 2Mbps.
====Bootloader====
This where you can install new Firmware to the Crazyflie.
[[Image:DefaultCrazyflieGUIBootloader.JPG|500px]]
The first thing you'll need to update is to build the Firmware version you want into a .bin file. You can do this by just running the <code>make</code> command in terminal while located inside the Firmware directory you have modified.
Once you have that .bin file built you:
#Open the bootloader shown
#Hold down the power button on the Crazyflie 2.0 for around 3 seconds until the 2 blue LED's flash and alternate. This puts the Crazyflie in bootloader mode. ('''NOTE:''' Recommend having '''ALL other Crazyflies OFF''' or else it could accidentally flash both Crazyflies.)
#Then hit ''Initiate bootloader cold boot'' (it should connect to the Crazyflie in bootloader mode after a few seconds, Status will change from 'Not Connected' to 'Connected')
#Hit ''Browse'' and find the .bin file you built earlier.
#Then click ''Program'' and wait for the progress bar to complete.
#Restart the Crazyflie in Firmware mode and make sure it starts up normally, if something seems wrong just repeat steps 2 through 6 again.
==Swarm Client==
The swarm Client is a re-creation of the Original Client but programmed in C and C++.
----
<center> [[Crazyflie Swarm]] | [[PC Client Software]] | [[USB Radio]] | [[Firmware]] </center>
80cb5997edf2f5d2c0a2f6f83b759f7753e77a44
83
82
2016-07-19T16:59:28Z
Jnoronha
3
Finished Logging
wikitext
text/x-wiki
The PC Client software comes in many forms. The out-of-the-box Client is written in Python and has a Graphical User Interface (GUI). The GUI is well suited for beginners, but can only support a single Radio and a single Crazyflie at a time. The easiest way to start out is with the [https://wiki.bitcraze.io/projects:virtualmachine:index Bitcraze Virtual Machine (VM)], which comes with all the files and dependencies pre-installed and can run on any computer (Windows, Mac, Linux, etc.).
For more advanced users who want to use the swarm capabilities of our platform will have to use the [[#Swarm Client|Swarm Client]] we developed in C and C++.
==[https://wiki.bitcraze.io/projects:virtualmachine:index Bitcraze VM]==
('''Note:''' The VM is updated frequently so the information below may be different than the current VM)
The Bitcraze wiki has a tutorial on [https://wiki.bitcraze.io/projects:virtualmachine:tutorials:vmware-win7 installing the VM]. Along with another tutorial on how to get started [https://www.bitcraze.io/getting-started-with-development/ using the VM].
These are both very simple starting guides that will help you become familiar with the VM.
===Crazyflie Client GUI===
On the VM you can find the Crazyflie Client Graphical User Interface (GUI). To run the Client you want to open a terminal and navigate to <code>projects/''''FIND PATH''''</code> and then run the command <code>sudo ./bin/cfclient</code>
(Alternatively, you can use the desktop to navigate to the folder and open a terminal there)
Once you do that you should see something similar to this:
[[Image:DefaultCrazyflieGUIMainScreen.JPG|500px]]
This is the main screen of the Client GUI and there are many tabs and features that you can access directly from this screen.
The most important parts of this screen are the following:
#Connect Button
#Bootloader (Crazyflie Drop Down -> Bootloader)
#Plotter Tab
#Log Blocks Tab
#Parameters Tab
====Connect Button====
This is where you will scan for Crazyflies that are powered ON. All Crazyflies not already connected will show up in the popup
[[Image:DefaultCrazyflieGUIConnectScreen.JPG|400px]]
We get a return that says <code>radio://0/45/2M</code>, this line is the identifier string of the Crazyflie we are trying to connect to.
What this is saying is that we got a return from a Radio (Radio 0 specifically), from a Crazyflie on Channel 45 using a data rate of 2Mbps.
====Bootloader====
This where you can install new Firmware to the Crazyflie.
[[Image:DefaultCrazyflieGUIBootloader.JPG|500px]]
The first thing you'll need to update is to build the Firmware version you want into a .bin file. You can do this by just running the <code>make</code> command in terminal while located inside the Firmware directory you have modified.
Once you have that .bin file built you:
#Open the bootloader shown
#Hold down the power button on the Crazyflie 2.0 for around 3 seconds until the 2 blue LED's flash and alternate. This puts the Crazyflie in bootloader mode. ('''NOTE:''' Recommend having '''ALL other Crazyflies OFF''' or else it could accidentally flash both Crazyflies.)
#Then hit ''Initiate bootloader cold boot'' (it should connect to the Crazyflie in bootloader mode after a few seconds, Status will change from 'Not Connected' to 'Connected')
#Hit ''Browse'' and find the .bin file you built earlier.
#Then click ''Program'' and wait for the progress bar to complete.
#Restart the Crazyflie in Firmware mode and make sure it starts up normally, if something seems wrong just repeat steps 2 through 6 again.
====Logging Tab====
Once you connect to a Crazyflie you can monitor certain log variables that have been set up. You will see a plot of the data similar to this:
[[Image:DefaultCrazyflieGUILoggerScreen.JPG|400px]]
On this screen we can do the following things:
*Dropdown Menu at the top of the screen
**Select which log block you want to plot on screen.
*Scale the X-axis of the plot by:
**Range
**Number of Samples
**Time in Seconds
**Manually
*Scale the Y-axis by:
**Automatically
**Manual Range
====Parameters Tab====
[[Image:DefaultCrazyflieGUIParametersScreen.JPG|400px]]
==Swarm Client==
The swarm Client is a re-creation of the Original Client but programmed in C and C++.
----
<center> [[Crazyflie Swarm]] | [[PC Client Software]] | [[USB Radio]] | [[Firmware]] </center>
f0be0ba5da4f75c6222a9c7d3cf0690f28dbb3c5
84
83
2016-07-19T17:07:34Z
Jnoronha
3
Finished Parameters Section
wikitext
text/x-wiki
The PC Client software comes in many forms. The out-of-the-box Client is written in Python and has a Graphical User Interface (GUI). The GUI is well suited for beginners, but can only support a single Radio and a single Crazyflie at a time. The easiest way to start out is with the [https://wiki.bitcraze.io/projects:virtualmachine:index Bitcraze Virtual Machine (VM)], which comes with all the files and dependencies pre-installed and can run on any computer (Windows, Mac, Linux, etc.).
For more advanced users who want to use the swarm capabilities of our platform will have to use the [[#Swarm Client|Swarm Client]] we developed in C and C++.
==[https://wiki.bitcraze.io/projects:virtualmachine:index Bitcraze VM]==
('''Note:''' The VM is updated frequently so the information below may be different than the current VM)
The Bitcraze wiki has a tutorial on [https://wiki.bitcraze.io/projects:virtualmachine:tutorials:vmware-win7 installing the VM]. Along with another tutorial on how to get started [https://www.bitcraze.io/getting-started-with-development/ using the VM].
These are both very simple starting guides that will help you become familiar with the VM.
===Crazyflie Client GUI===
On the VM you can find the Crazyflie Client Graphical User Interface (GUI). To run the Client you want to open a terminal and navigate to <code>projects/''''FIND PATH''''</code> and then run the command <code>sudo ./bin/cfclient</code>
(Alternatively, you can use the desktop to navigate to the folder and open a terminal there)
Once you do that you should see something similar to this:
[[Image:DefaultCrazyflieGUIMainScreen.JPG|500px]]
This is the main screen of the Client GUI and there are many tabs and features that you can access directly from this screen.
The most important parts of this screen are the following:
#Connect Button
#Bootloader (Crazyflie Drop Down -> Bootloader)
#Plotter Tab
#Log Blocks Tab
#Parameters Tab
====Connect Button====
This is where you will scan for Crazyflies that are powered ON. All Crazyflies not already connected will show up in the popup
[[Image:DefaultCrazyflieGUIConnectScreen.JPG|400px]]
We get a return that says <code>radio://0/45/2M</code>, this line is the identifier string of the Crazyflie we are trying to connect to.
What this is saying is that we got a return from a Radio (Radio 0 specifically), from a Crazyflie on Channel 45 using a data rate of 2Mbps.
====Bootloader====
This where you can install new Firmware to the Crazyflie.
[[Image:DefaultCrazyflieGUIBootloader.JPG|500px]]
The first thing you'll need to update is to build the Firmware version you want into a .bin file. You can do this by just running the <code>make</code> command in terminal while located inside the Firmware directory you have modified.
Once you have that .bin file built you:
#Open the bootloader shown
#Hold down the power button on the Crazyflie 2.0 for around 3 seconds until the 2 blue LED's flash and alternate. This puts the Crazyflie in bootloader mode. ('''NOTE:''' Recommend having '''ALL other Crazyflies OFF''' or else it could accidentally flash both Crazyflies.)
#Then hit ''Initiate bootloader cold boot'' (it should connect to the Crazyflie in bootloader mode after a few seconds, Status will change from 'Not Connected' to 'Connected')
#Hit ''Browse'' and find the .bin file you built earlier.
#Then click ''Program'' and wait for the progress bar to complete.
#Restart the Crazyflie in Firmware mode and make sure it starts up normally, if something seems wrong just repeat steps 2 through 6 again.
====Logging Tab====
Once you connect to a Crazyflie you can monitor certain log variables that have been set up. You will see a plot of the data similar to this:
[[Image:DefaultCrazyflieGUILoggerScreen.JPG|400px]]
On this screen we can do the following things:
*Dropdown Menu at the top of the screen
**Select which log block you want to plot on screen.
*Scale the X-axis of the plot by:
**Range
**Number of Samples
**Time in Seconds
**Manually
*Scale the Y-axis by:
**Automatically
**Manual Range
====Parameters Tab====
This tab displays all the parameters currently set up on the Crazyflie Firmware. Once you connect to a Crazyflie it lists these parameters in a table format similar to below:
[[Image:DefaultCrazyflieGUIParametersScreen.JPG|400px]]
For each parameter we get its Name, Variable Type, Access Type (Read/Write), and its Current Value.
We can also modify the parameter values on this screen in real-time and the changes will be sent to the Crazyflie automatically.
('''Note:''' Any parameter changes made on this screen are NOT preserved when you turn OFF the Crazyflie.)
==Swarm Client==
The swarm Client is a re-creation of the Original Client but programmed in C and C++.
----
<center> [[Crazyflie Swarm]] | [[PC Client Software]] | [[USB Radio]] | [[Firmware]] </center>
654954ef38cb901d64d270c260b129d74380ea5d
85
84
2016-07-19T17:41:40Z
Jnoronha
3
/* Swarm Client */ Added up to step 3 in the Swarm Client
wikitext
text/x-wiki
The PC Client software comes in many forms. The out-of-the-box Client is written in Python and has a Graphical User Interface (GUI). The GUI is well suited for beginners, but can only support a single Radio and a single Crazyflie at a time. The easiest way to start out is with the [https://wiki.bitcraze.io/projects:virtualmachine:index Bitcraze Virtual Machine (VM)], which comes with all the files and dependencies pre-installed and can run on any computer (Windows, Mac, Linux, etc.).
For more advanced users who want to use the swarm capabilities of our platform will have to use the [[#Swarm Client|Swarm Client]] we developed in C and C++.
==[https://wiki.bitcraze.io/projects:virtualmachine:index Bitcraze VM]==
('''Note:''' The VM is updated frequently so the information below may be different than the current VM)
The Bitcraze wiki has a tutorial on [https://wiki.bitcraze.io/projects:virtualmachine:tutorials:vmware-win7 installing the VM]. Along with another tutorial on how to get started [https://www.bitcraze.io/getting-started-with-development/ using the VM].
These are both very simple starting guides that will help you become familiar with the VM.
===Crazyflie Client GUI===
On the VM you can find the Crazyflie Client Graphical User Interface (GUI). To run the Client you want to open a terminal and navigate to <code>projects/''''FIND PATH''''</code> and then run the command <code>sudo ./bin/cfclient</code>
(Alternatively, you can use the desktop to navigate to the folder and open a terminal there)
Once you do that you should see something similar to this:
[[Image:DefaultCrazyflieGUIMainScreen.JPG|500px]]
This is the main screen of the Client GUI and there are many tabs and features that you can access directly from this screen.
The most important parts of this screen are the following:
#Connect Button
#Bootloader (Crazyflie Drop Down -> Bootloader)
#Plotter Tab
#Log Blocks Tab
#Parameters Tab
====Connect Button====
This is where you will scan for Crazyflies that are powered ON. All Crazyflies not already connected will show up in the popup
[[Image:DefaultCrazyflieGUIConnectScreen.JPG|400px]]
We get a return that says <code>radio://0/45/2M</code>, this line is the identifier string of the Crazyflie we are trying to connect to.
What this is saying is that we got a return from a Radio (Radio 0 specifically), from a Crazyflie on Channel 45 using a data rate of 2Mbps.
====Bootloader====
This where you can install new Firmware to the Crazyflie.
[[Image:DefaultCrazyflieGUIBootloader.JPG|500px]]
The first thing you'll need to update is to build the Firmware version you want into a .bin file. You can do this by just running the <code>make</code> command in terminal while located inside the Firmware directory you have modified.
Once you have that .bin file built you:
#Open the bootloader shown
#Hold down the power button on the Crazyflie 2.0 for around 3 seconds until the 2 blue LED's flash and alternate. This puts the Crazyflie in bootloader mode. ('''NOTE:''' Recommend having '''ALL other Crazyflies OFF''' or else it could accidentally flash both Crazyflies.)
#Then hit ''Initiate bootloader cold boot'' (it should connect to the Crazyflie in bootloader mode after a few seconds, Status will change from 'Not Connected' to 'Connected')
#Hit ''Browse'' and find the .bin file you built earlier.
#Then click ''Program'' and wait for the progress bar to complete.
#Restart the Crazyflie in Firmware mode and make sure it starts up normally, if something seems wrong just repeat steps 2 through 6 again.
====Logging Tab====
Once you connect to a Crazyflie you can monitor certain log variables that have been set up. You will see a plot of the data similar to this:
[[Image:DefaultCrazyflieGUILoggerScreen.JPG|400px]]
On this screen we can do the following things:
*Dropdown Menu at the top of the screen
**Select which log block you want to plot on screen.
*Scale the X-axis of the plot by:
**Range
**Number of Samples
**Time in Seconds
**Manually
*Scale the Y-axis by:
**Automatically
**Manual Range
====Parameters Tab====
This tab displays all the parameters currently set up on the Crazyflie Firmware. Once you connect to a Crazyflie it lists these parameters in a table format similar to below:
[[Image:DefaultCrazyflieGUIParametersScreen.JPG|400px]]
For each parameter we get its Name, Variable Type, Access Type (Read/Write), and its Current Value.
We can also modify the parameter values on this screen in real-time and the changes will be sent to the Crazyflie automatically.
('''Note:''' Any parameter changes made on this screen are NOT preserved when you turn OFF the Crazyflie.)
==Swarm Client==
The swarm Client is a re-creation of the Original Client but programmed in C and C++.
The benefit of this is that
*We use a unified language between Client and Firmware
*Easily migrate this platform to any linux distribution that can install the Crazyflie dependencies.
**Our platform code itself requires only the VRPN libraries and a generic C compiler.
===Using the Swarm Client===
The Swarm Client uses the terminal interface for User Input.
:1. The first thing you want to do before any testing is to run the <code>sudo make</code> command in the Swarm Client directory. (Yes, the 'sudo' is necessary)
::This will make sure you have all the necessary dependencies, that the code is error free, and then it will build an executable (.exe) file of the Swarm Client code. An error free make will look something like this:
:2. Before we run the .exe we need to run through a checklist
::*Camera System is Turned on and Crazyflie Trackables are opened and visible.
::*Radios are plugged into the USB Ports on the Client computer.
::*Crazyflies are ON and NOT in an Error State.
:3. Run the executable file using the command <code>sudo ./eris_vrpn</code> in the same directory (Yes, the 'sudo' is necessary). This will start the program initialization and a bunch of status info will flood the screen. You will know the program is ready for input when you see the following:
----
<center> [[Crazyflie Swarm]] | [[PC Client Software]] | [[USB Radio]] | [[Firmware]] </center>
f2e108f3a27b1948b2c16080d04d303062591da7
94
85
2016-07-19T18:11:03Z
Jnoronha
3
/* Swarm Client */ Added Keyboard Commands
wikitext
text/x-wiki
The PC Client software comes in many forms. The out-of-the-box Client is written in Python and has a Graphical User Interface (GUI). The GUI is well suited for beginners, but can only support a single Radio and a single Crazyflie at a time. The easiest way to start out is with the [https://wiki.bitcraze.io/projects:virtualmachine:index Bitcraze Virtual Machine (VM)], which comes with all the files and dependencies pre-installed and can run on any computer (Windows, Mac, Linux, etc.).
For more advanced users who want to use the swarm capabilities of our platform will have to use the [[#Swarm Client|Swarm Client]] we developed in C and C++.
==[https://wiki.bitcraze.io/projects:virtualmachine:index Bitcraze VM]==
('''Note:''' The VM is updated frequently so the information below may be different than the current VM)
The Bitcraze wiki has a tutorial on [https://wiki.bitcraze.io/projects:virtualmachine:tutorials:vmware-win7 installing the VM]. Along with another tutorial on how to get started [https://www.bitcraze.io/getting-started-with-development/ using the VM].
These are both very simple starting guides that will help you become familiar with the VM.
===Crazyflie Client GUI===
On the VM you can find the Crazyflie Client Graphical User Interface (GUI). To run the Client you want to open a terminal and navigate to <code>projects/''''FIND PATH''''</code> and then run the command <code>sudo ./bin/cfclient</code>
(Alternatively, you can use the desktop to navigate to the folder and open a terminal there)
Once you do that you should see something similar to this:
[[Image:DefaultCrazyflieGUIMainScreen.JPG|500px]]
This is the main screen of the Client GUI and there are many tabs and features that you can access directly from this screen.
The most important parts of this screen are the following:
#Connect Button
#Bootloader (Crazyflie Drop Down -> Bootloader)
#Plotter Tab
#Log Blocks Tab
#Parameters Tab
====Connect Button====
This is where you will scan for Crazyflies that are powered ON. All Crazyflies not already connected will show up in the popup
[[Image:DefaultCrazyflieGUIConnectScreen.JPG|400px]]
We get a return that says <code>radio://0/45/2M</code>, this line is the identifier string of the Crazyflie we are trying to connect to.
What this is saying is that we got a return from a Radio (Radio 0 specifically), from a Crazyflie on Channel 45 using a data rate of 2Mbps.
====Bootloader====
This where you can install new Firmware to the Crazyflie.
[[Image:DefaultCrazyflieGUIBootloader.JPG|500px]]
The first thing you'll need to update is to build the Firmware version you want into a .bin file. You can do this by just running the <code>make</code> command in terminal while located inside the Firmware directory you have modified.
Once you have that .bin file built you:
#Open the bootloader shown
#Hold down the power button on the Crazyflie 2.0 for around 3 seconds until the 2 blue LED's flash and alternate. This puts the Crazyflie in bootloader mode. ('''NOTE:''' Recommend having '''ALL other Crazyflies OFF''' or else it could accidentally flash both Crazyflies.)
#Then hit ''Initiate bootloader cold boot'' (it should connect to the Crazyflie in bootloader mode after a few seconds, Status will change from 'Not Connected' to 'Connected')
#Hit ''Browse'' and find the .bin file you built earlier.
#Then click ''Program'' and wait for the progress bar to complete.
#Restart the Crazyflie in Firmware mode and make sure it starts up normally, if something seems wrong just repeat steps 2 through 6 again.
====Logging Tab====
Once you connect to a Crazyflie you can monitor certain log variables that have been set up. You will see a plot of the data similar to this:
[[Image:DefaultCrazyflieGUILoggerScreen.JPG|400px]]
On this screen we can do the following things:
*Dropdown Menu at the top of the screen
**Select which log block you want to plot on screen.
*Scale the X-axis of the plot by:
**Range
**Number of Samples
**Time in Seconds
**Manually
*Scale the Y-axis by:
**Automatically
**Manual Range
====Parameters Tab====
This tab displays all the parameters currently set up on the Crazyflie Firmware. Once you connect to a Crazyflie it lists these parameters in a table format similar to below:
[[Image:DefaultCrazyflieGUIParametersScreen.JPG|400px]]
For each parameter we get its Name, Variable Type, Access Type (Read/Write), and its Current Value.
We can also modify the parameter values on this screen in real-time and the changes will be sent to the Crazyflie automatically.
('''Note:''' Any parameter changes made on this screen are NOT preserved when you turn OFF the Crazyflie.)
==Swarm Client==
The swarm Client is a re-creation of the Original Client but programmed in C and C++.
The benefit of this is that
*We use a unified language between Client and Firmware
*Easily migrate this platform to any linux distribution that can install the Crazyflie dependencies.
**Our platform code itself requires only the VRPN libraries and a generic C compiler.
===Using the Swarm Client===
The Swarm Client uses the terminal interface for User Input.
:1. The first thing you want to do before any testing is to run the <code>sudo make</code> command in the Swarm Client directory. (Yes, the 'sudo' is necessary)
::This will make sure you have all the necessary dependencies, that the code is error free, and then it will build an executable (.exe) file of the Swarm Client code. An error free make will look something like this:
::[[Image:CrazyflieTerminalPostMake.png|400px]]
::There will be warnings, but those don't cause any issues right now.
:2. Pre-Test Checklist
::*Camera System is Turned on and Crazyflie Trackables are opened and visible.
::*Radios are plugged into the USB Ports on the Client computer.
::*Crazyflies are ON and NOT in an Error State.
:3. Run the executable file using the command <code>sudo ./eris_vrpn</code> in the same directory (Yes, the 'sudo' is necessary). This will start the program initialization and a bunch of status info will flood the screen. You will know the program is ready for input when you see the following:
::[[Image:CrazyflieTerminalProgramStarted.png|400px]]
::This means that the Crazyflie yaw has been synchronized with the Camera system and they are ready to fly.
:4. Input a Keyboard Command
::This will depend on what you have programmed as the keyboard input commands. As of 7/19/16 we have the following Keyboard Commands active:
::*'1' - Rotates Yaw of Crazyflie1 +45 degrees
::*'2' - Rotates Yaw of Crazyflie1 -45 degrees
::*'q' - Ends Main Loop (OBSOLETE - Replaced with ctrl + c)
::*'e' - Landing Mode (for ALL Crazyflies)
::*'t' - Crazyflie1 Take-Off
::*'y' - Crazyflie2 Take-Off
::*'u' - Crazyflie3 Take-Off
::*'i' - Crazyflie4 Take-Off
::*'h' - Hand Gesture Mode (for ALL Crazyflies)
::*'m' - Mirror Mode (for ALL Crazyflies)
::*ctrl+c - Quits Program, performs all cleanup.
::An example of what this would look like in the Terminal is shown here:
::[[Image:CrazyflieTerminalKeyboardInput.png|400px]]
----
<center> [[Crazyflie Swarm]] | [[PC Client Software]] | [[USB Radio]] | [[Firmware]] </center>
35ea54767ef9b99757ee6f7b68ae21868d19320f
95
94
2016-07-19T18:31:31Z
Jnoronha
3
/* Swarm Client */ Added Keyboard Input figure and finished 'Using the Platform Section'
wikitext
text/x-wiki
The PC Client software comes in many forms. The out-of-the-box Client is written in Python and has a Graphical User Interface (GUI). The GUI is well suited for beginners, but can only support a single Radio and a single Crazyflie at a time. The easiest way to start out is with the [https://wiki.bitcraze.io/projects:virtualmachine:index Bitcraze Virtual Machine (VM)], which comes with all the files and dependencies pre-installed and can run on any computer (Windows, Mac, Linux, etc.).
For more advanced users who want to use the swarm capabilities of our platform will have to use the [[#Swarm Client|Swarm Client]] we developed in C and C++.
==[https://wiki.bitcraze.io/projects:virtualmachine:index Bitcraze VM]==
('''Note:''' The VM is updated frequently so the information below may be different than the current VM)
The Bitcraze wiki has a tutorial on [https://wiki.bitcraze.io/projects:virtualmachine:tutorials:vmware-win7 installing the VM]. Along with another tutorial on how to get started [https://www.bitcraze.io/getting-started-with-development/ using the VM].
These are both very simple starting guides that will help you become familiar with the VM.
===Crazyflie Client GUI===
On the VM you can find the Crazyflie Client Graphical User Interface (GUI). To run the Client you want to open a terminal and navigate to <code>projects/''''FIND PATH''''</code> and then run the command <code>sudo ./bin/cfclient</code>
(Alternatively, you can use the desktop to navigate to the folder and open a terminal there)
Once you do that you should see something similar to this:
[[Image:DefaultCrazyflieGUIMainScreen.JPG|500px]]
This is the main screen of the Client GUI and there are many tabs and features that you can access directly from this screen.
The most important parts of this screen are the following:
#Connect Button
#Bootloader (Crazyflie Drop Down -> Bootloader)
#Plotter Tab
#Log Blocks Tab
#Parameters Tab
====Connect Button====
This is where you will scan for Crazyflies that are powered ON. All Crazyflies not already connected will show up in the popup
[[Image:DefaultCrazyflieGUIConnectScreen.JPG|400px]]
We get a return that says <code>radio://0/45/2M</code>, this line is the identifier string of the Crazyflie we are trying to connect to.
What this is saying is that we got a return from a Radio (Radio 0 specifically), from a Crazyflie on Channel 45 using a data rate of 2Mbps.
====Bootloader====
This where you can install new Firmware to the Crazyflie.
[[Image:DefaultCrazyflieGUIBootloader.JPG|500px]]
The first thing you'll need to update is to build the Firmware version you want into a .bin file. You can do this by just running the <code>make</code> command in terminal while located inside the Firmware directory you have modified.
Once you have that .bin file built you:
#Open the bootloader shown
#Hold down the power button on the Crazyflie 2.0 for around 3 seconds until the 2 blue LED's flash and alternate. This puts the Crazyflie in bootloader mode. ('''NOTE:''' Recommend having '''ALL other Crazyflies OFF''' or else it could accidentally flash both Crazyflies.)
#Then hit ''Initiate bootloader cold boot'' (it should connect to the Crazyflie in bootloader mode after a few seconds, Status will change from 'Not Connected' to 'Connected')
#Hit ''Browse'' and find the .bin file you built earlier.
#Then click ''Program'' and wait for the progress bar to complete.
#Restart the Crazyflie in Firmware mode and make sure it starts up normally, if something seems wrong just repeat steps 2 through 6 again.
====Logging Tab====
Once you connect to a Crazyflie you can monitor certain log variables that have been set up. You will see a plot of the data similar to this:
[[Image:DefaultCrazyflieGUILoggerScreen.JPG|400px]]
On this screen we can do the following things:
*Dropdown Menu at the top of the screen
**Select which log block you want to plot on screen.
*Scale the X-axis of the plot by:
**Range
**Number of Samples
**Time in Seconds
**Manually
*Scale the Y-axis by:
**Automatically
**Manual Range
====Parameters Tab====
This tab displays all the parameters currently set up on the Crazyflie Firmware. Once you connect to a Crazyflie it lists these parameters in a table format similar to below:
[[Image:DefaultCrazyflieGUIParametersScreen.JPG|400px]]
For each parameter we get its Name, Variable Type, Access Type (Read/Write), and its Current Value.
We can also modify the parameter values on this screen in real-time and the changes will be sent to the Crazyflie automatically.
('''Note:''' Any parameter changes made on this screen are NOT preserved when you turn OFF the Crazyflie.)
==Swarm Client==
The swarm Client is a re-creation of the Original Client but programmed in C and C++.
The benefit of this is that
*We use a unified language between Client and Firmware
*Easily migrate this platform to any linux distribution that can install the Crazyflie dependencies.
**Our platform code itself requires only the VRPN libraries and a generic C compiler.
===Using the Swarm Client===
The Swarm Client uses the terminal interface for User Input.
:1. The first thing you want to do before any testing is to run the <code>sudo make</code> command in the Swarm Client directory. (Yes, the 'sudo' is necessary)
::This will make sure you have all the necessary dependencies, that the code is error free, and then it will build an executable (.exe) file of the Swarm Client code. An error free make will look something like this:
::[[Image:CrazyflieTerminalPostMake.png|400px]]
::There will be warnings, but those don't cause any issues right now.
:2. Pre-Test Checklist
::*Camera System is Turned on and Crazyflie Trackables are opened and visible.
::*Radios are plugged into the USB Ports on the Client computer.
::*Crazyflies are ON and NOT in an Error State.
:3. Run the executable file using the command <code>sudo ./eris_vrpn</code> in the same directory (Yes, the 'sudo' is necessary). This will start the program initialization and a bunch of status info will flood the screen. You will know the program is ready for input when you see the following:
::[[Image:CrazyflieTerminalProgramStarted.png|400px]]
::This means that the Crazyflie yaw has been synchronized with the Camera system and they are ready to fly.
:4. Input a Keyboard Command
::This will depend on what you have programmed as the keyboard input commands. As of 7/19/16 we have the following Keyboard Commands active:
::*'1' - Rotates Yaw of Crazyflie1 +45 degrees
::*'2' - Rotates Yaw of Crazyflie1 -45 degrees
::*'q' - Ends Main Loop (OBSOLETE - Replaced with ctrl + c)
::*'e' - Landing Mode (for ALL Crazyflies)
::*'t' - Crazyflie1 Take-Off
::*'y' - Crazyflie2 Take-Off
::*'u' - Crazyflie3 Take-Off
::*'i' - Crazyflie4 Take-Off
::*'h' - Hand Gesture Mode (for ALL Crazyflies)
::*'m' - Mirror Mode (for ALL Crazyflies)
::*ctrl+c - Quits Program, performs all cleanup.
::An example of what this would look like in the Terminal is shown here:
::[[Image:CrazyflieTerminalKeyboardInput.png|400px]]
::So you can see we commanded all 4 Crazyflies to take off (t,y,u,i), then activated Landing Mode (e), then activated Hand Mode (h), and then Ended the Program (ctrl+c).
:5. End Program when finished (ctrl+c)
::This will end the program loop, print the current battery levels, and Delete the Radio pointers (shown at the end of the previous figure)
----
<center> [[Crazyflie Swarm]] | [[PC Client Software]] | [[USB Radio]] | [[Firmware]] </center>
03e4d1e683f4e220188bc33aa996d02a4a7e1343
96
95
2016-07-19T18:41:28Z
Jnoronha
3
/* Swarm Client */ Added Initial state Terminal figure
wikitext
text/x-wiki
The PC Client software comes in many forms. The out-of-the-box Client is written in Python and has a Graphical User Interface (GUI). The GUI is well suited for beginners, but can only support a single Radio and a single Crazyflie at a time. The easiest way to start out is with the [https://wiki.bitcraze.io/projects:virtualmachine:index Bitcraze Virtual Machine (VM)], which comes with all the files and dependencies pre-installed and can run on any computer (Windows, Mac, Linux, etc.).
For more advanced users who want to use the swarm capabilities of our platform will have to use the [[#Swarm Client|Swarm Client]] we developed in C and C++.
==[https://wiki.bitcraze.io/projects:virtualmachine:index Bitcraze VM]==
('''Note:''' The VM is updated frequently so the information below may be different than the current VM)
The Bitcraze wiki has a tutorial on [https://wiki.bitcraze.io/projects:virtualmachine:tutorials:vmware-win7 installing the VM]. Along with another tutorial on how to get started [https://www.bitcraze.io/getting-started-with-development/ using the VM].
These are both very simple starting guides that will help you become familiar with the VM.
===Crazyflie Client GUI===
On the VM you can find the Crazyflie Client Graphical User Interface (GUI). To run the Client you want to open a terminal and navigate to <code>projects/''''FIND PATH''''</code> and then run the command <code>sudo ./bin/cfclient</code>
(Alternatively, you can use the desktop to navigate to the folder and open a terminal there)
Once you do that you should see something similar to this:
[[Image:DefaultCrazyflieGUIMainScreen.JPG|500px]]
This is the main screen of the Client GUI and there are many tabs and features that you can access directly from this screen.
The most important parts of this screen are the following:
#Connect Button
#Bootloader (Crazyflie Drop Down -> Bootloader)
#Plotter Tab
#Log Blocks Tab
#Parameters Tab
====Connect Button====
This is where you will scan for Crazyflies that are powered ON. All Crazyflies not already connected will show up in the popup
[[Image:DefaultCrazyflieGUIConnectScreen.JPG|400px]]
We get a return that says <code>radio://0/45/2M</code>, this line is the identifier string of the Crazyflie we are trying to connect to.
What this is saying is that we got a return from a Radio (Radio 0 specifically), from a Crazyflie on Channel 45 using a data rate of 2Mbps.
====Bootloader====
This where you can install new Firmware to the Crazyflie.
[[Image:DefaultCrazyflieGUIBootloader.JPG|500px]]
The first thing you'll need to update is to build the Firmware version you want into a .bin file. You can do this by just running the <code>make</code> command in terminal while located inside the Firmware directory you have modified.
Once you have that .bin file built you:
#Open the bootloader shown
#Hold down the power button on the Crazyflie 2.0 for around 3 seconds until the 2 blue LED's flash and alternate. This puts the Crazyflie in bootloader mode. ('''NOTE:''' Recommend having '''ALL other Crazyflies OFF''' or else it could accidentally flash both Crazyflies.)
#Then hit ''Initiate bootloader cold boot'' (it should connect to the Crazyflie in bootloader mode after a few seconds, Status will change from 'Not Connected' to 'Connected')
#Hit ''Browse'' and find the .bin file you built earlier.
#Then click ''Program'' and wait for the progress bar to complete.
#Restart the Crazyflie in Firmware mode and make sure it starts up normally, if something seems wrong just repeat steps 2 through 6 again.
====Logging Tab====
Once you connect to a Crazyflie you can monitor certain log variables that have been set up. You will see a plot of the data similar to this:
[[Image:DefaultCrazyflieGUILoggerScreen.JPG|400px]]
On this screen we can do the following things:
*Dropdown Menu at the top of the screen
**Select which log block you want to plot on screen.
*Scale the X-axis of the plot by:
**Range
**Number of Samples
**Time in Seconds
**Manually
*Scale the Y-axis by:
**Automatically
**Manual Range
====Parameters Tab====
This tab displays all the parameters currently set up on the Crazyflie Firmware. Once you connect to a Crazyflie it lists these parameters in a table format similar to below:
[[Image:DefaultCrazyflieGUIParametersScreen.JPG|400px]]
For each parameter we get its Name, Variable Type, Access Type (Read/Write), and its Current Value.
We can also modify the parameter values on this screen in real-time and the changes will be sent to the Crazyflie automatically.
('''Note:''' Any parameter changes made on this screen are NOT preserved when you turn OFF the Crazyflie.)
==Swarm Client==
The swarm Client is a re-creation of the Original Client but programmed in C and C++.
The benefit of this is that
*We use a unified language between Client and Firmware
*Easily migrate this platform to any linux distribution that can install the Crazyflie dependencies.
**Our platform code itself requires only the VRPN libraries and a generic C compiler.
===Using the Swarm Client===
The Swarm Client uses the terminal interface for User Input.
[[Image:CrazyflieTerminalInitial.png|400px]]
Here we see what the initial Terminal looks like before we do anything.
:1. The first thing you want to do before any testing is to run the <code>sudo make</code> command in the Swarm Client directory. (Yes, the 'sudo' is necessary)
::This will make sure you have all the necessary dependencies, that the code is error free, and then it will build an executable (.exe) file of the Swarm Client code. An error free make will look something like this:
::[[Image:CrazyflieTerminalPostMake.png|400px]]
::There will be warnings, but those don't cause any issues right now.
:2. Pre-Test Checklist
::*Camera System is Turned on and Crazyflie Trackables are opened and visible.
::*Radios are plugged into the USB Ports on the Client computer.
::*Crazyflies are ON and NOT in an Error State.
:3. Run the executable file using the command <code>sudo ./eris_vrpn</code> in the same directory (Yes, the 'sudo' is necessary). This will start the program initialization and a bunch of status info will flood the screen. You will know the program is ready for input when you see the following:
::[[Image:CrazyflieTerminalProgramStarted.png|400px]]
::This means that the Crazyflie yaw has been synchronized with the Camera system and they are ready to fly.
:4. Input a Keyboard Command
::This will depend on what you have programmed as the keyboard input commands. As of 7/19/16 we have the following Keyboard Commands active:
::*'1' - Rotates Yaw of Crazyflie1 +45 degrees
::*'2' - Rotates Yaw of Crazyflie1 -45 degrees
::*'q' - Ends Main Loop (OBSOLETE - Replaced with ctrl + c)
::*'e' - Landing Mode (for ALL Crazyflies)
::*'t' - Crazyflie1 Take-Off
::*'y' - Crazyflie2 Take-Off
::*'u' - Crazyflie3 Take-Off
::*'i' - Crazyflie4 Take-Off
::*'h' - Hand Gesture Mode (for ALL Crazyflies)
::*'m' - Mirror Mode (for ALL Crazyflies)
::*ctrl+c - Quits Program, performs all cleanup.
::An example of what this would look like in the Terminal is shown here:
::[[Image:CrazyflieTerminalKeyboardInput.png|400px]]
::So you can see we commanded all 4 Crazyflies to take off (t,y,u,i), then activated Landing Mode (e), then activated Hand Mode (h), and then Ended the Program (ctrl+c).
:5. End Program when finished (ctrl+c)
::This will end the program loop, print the current battery levels, and Delete the Radio pointers (shown at the end of the previous figure)
----
<center> [[Crazyflie Swarm]] | [[PC Client Software]] | [[USB Radio]] | [[Firmware]] </center>
926454589f42bf17b88608afa4c643071a3275a7
Firmware
0
26
58
2016-07-12T18:09:04Z
Jnoronha
3
Added Navigation bar
wikitext
text/x-wiki
----
<center> [[Crazyflie Swarm]] | [[PC Client Software]] | [[USB Radio]] | [[Firmware]] </center>
6a8ddcb3ad33d00f0c67854f6f60de327dbe70cb
Controller
0
5
60
20
2016-07-12T20:50:26Z
Jnoronha
3
Added overview of original Firmware PID's
wikitext
text/x-wiki
The Crazyflie platform is completely customizable when it comes to the control design. As long as the controller can be written in C or C++, we can implement it in the Platform. This applies to both the controllers run on the PC Client and the controllers run on the Firmware of the Crazyflie. Originally the only controllers in the Platform were Firmware PID's that controlled the angular position and rates of the Crazyflie for hand flight. The original controller layout can be seen in '''Figure 1'''.
Below you will find documentation on the different types of Controllers that have been applied to the platform, organized by their location in the Platform.
== PC Client ==
=== PID Controllers (Position and Yaw) ===
The first controller implemented on the Client was a PID controller used to stabilize the Crazyflie's position in X, Y, and Z.
== Firmware ==
=== Original PID Controllers (Angular Rotation) ===
On the Crazyflie Firmware there are 5 PID controllers as seen here:
[[Image:FirmwareOnlyPIDArchitecture.png|500px]]
The Pitch and Roll angular position PID's receive constant setpoints from some outside source (gamepad controller or automated controller). The outputs of those angular position controllers is then fed into the angular rate controllers as shown. This final output is then fed into the Motor Command block which converts the angular rate setpoints into motor commands.
5819aea3997ca1dbd2284b2895304061ccd531eb
61
60
2016-07-13T16:32:14Z
Jnoronha
3
Added full PID client figure
wikitext
text/x-wiki
The Crazyflie platform is completely customizable when it comes to the control design. As long as the controller can be written in C or C++, we can implement it in the Platform. This applies to both the controllers run on the PC Client and the controllers run on the Firmware of the Crazyflie. Originally the only controllers in the Platform were Firmware PID's that controlled the angular position and rates of the Crazyflie for hand flight. The original controller layout can be seen in '''Figure 1'''.
Below you will find documentation on the different types of Controllers that have been applied to the platform, organized by their location in the Platform.
== Firmware ==
=== Original PID Controllers (Angular Rotation) ===
Directly on the Crazyflie Firmware there are 5 PID controllers as seen here:
[[Image:FirmwareOnlyPIDArchitecture.png|500px]]
The Pitch and Roll angular position PID's receive constant setpoints from some outside source (gamepad controller or automated controller). The outputs of those angular position controllers is then fed into the angular rate controllers as shown. This final output is then fed into the Motor Command block which converts the angular rate setpoints into motor commands.
----
===State Estimator===
('''***NOT YET IMPLEMENTED***''')
Bitcraze is currently working on adding a state estimator onto the Firmware to handle control calculations instead of the PID.
The code is in place but the controller is not yet used as of '''7/13/16'''.
== PC Client ==
=== PID Controllers (Position and Yaw) ===
The first controller implemented on the Client were 4 PID controllers used to stabilize the Crazyflie's position in X, Y, and Z, as well as angular position in Yaw respectively. These PID's feed directly into the Firmware PID's as seen here:
[[Image:CompletePIDArchitectureFigure.png|500px]]
The controllers inside the red box are the original PID controllers located on the [Controller:Firmware|Original PID Controllers (Angular Rotation) Firmware]
9712be7d0cb7f7b8d740bc52c4c3e1a242705794
62
61
2016-07-13T16:37:36Z
Jnoronha
3
added link to original pid header in client PID section
wikitext
text/x-wiki
The Crazyflie platform is completely customizable when it comes to the control design. As long as the controller can be written in C or C++, we can implement it in the Platform. This applies to both the controllers run on the PC Client and the controllers run on the Firmware of the Crazyflie. Originally the only controllers in the Platform were Firmware PID's that controlled the angular position and rates of the Crazyflie for hand flight. The original controller layout can be seen in '''Figure 1'''.
Below you will find documentation on the different types of Controllers that have been applied to the platform, organized by their location in the Platform.
== Firmware ==
=== Original PID Controllers (Angular Rotation) ===
Directly on the Crazyflie Firmware there are 5 PID controllers as seen here:
[[Image:FirmwareOnlyPIDArchitecture.png|500px]]
The Pitch and Roll angular position PID's receive constant setpoints from some outside source (gamepad controller or automated controller). The outputs of those angular position controllers is then fed into the angular rate controllers as shown. This final output is then fed into the Motor Command block which converts the angular rate setpoints into motor commands.
----
===State Estimator===
('''***NOT YET IMPLEMENTED***''')
Bitcraze is currently working on adding a state estimator onto the Firmware to handle control calculations instead of the PID.
The code is in place but the controller is not yet used as of '''7/13/16'''.
== PC Client ==
=== PID Controllers (Position and Yaw) ===
The first controller implemented on the Client were 4 PID controllers used to stabilize the Crazyflie's position in X, Y, and Z, as well as angular position in Yaw respectively. These PID's feed directly into the Firmware PID's as seen here:
[[Image:CompletePIDArchitectureFigure.png|500px]]
The controllers inside the red box are the original PID controllers located on the Firmware as shown in the [[#Original PID Controllers (Angular Rotation)|Original PID's]].
b10e0ed950c5f80686f4c413ecae0ca5544648f4
63
62
2016-07-13T17:04:01Z
Jnoronha
3
Added many steps to PID controller init
wikitext
text/x-wiki
The Crazyflie platform is completely customizable when it comes to the control design. As long as the controller can be written in C or C++, we can implement it in the Platform. This applies to both the controllers run on the PC Client and the controllers run on the Firmware of the Crazyflie. Originally the only controllers in the Platform were Firmware PID's that controlled the angular position and rates of the Crazyflie for hand flight. The original controller layout can be seen in '''Figure 1'''.
Below you will find documentation on the different types of Controllers that have been applied to the platform, organized by their location in the Platform.
== Firmware ==
=== Original PID Controllers (Angular Rotation) ===
Directly on the Crazyflie Firmware there are 5 PID controllers as seen here:
[[Image:FirmwareOnlyPIDArchitecture.png|500px]]
The Pitch and Roll angular position PID's receive constant setpoints from some outside source (gamepad controller or automated controller). The outputs of those angular position controllers is then fed into the angular rate controllers as shown. This final output is then fed into the Motor Command block which converts the angular rate setpoints into motor commands.
----
===State Estimator===
('''***NOT YET IMPLEMENTED***''')
Bitcraze is currently working on adding a state estimator onto the Firmware to handle control calculations instead of the PID.
The code is in place but the controller is not yet used as of '''7/13/16'''.
== PC Client ==
=== PID Controllers (Position and Yaw) ===
The first controller implemented on the Client were 4 PID controllers used to stabilize the Crazyflie's position in X, Y, and Z, as well as angular position in Yaw respectively. These PID's feed directly into the Firmware PID's as seen here:
[[Image:CompletePIDArchitectureFigure.png|500px]]
The controllers inside the red box are the original PID controllers located on the Firmware as shown above in the [[#Original PID Controllers (Angular Rotation)|Original PID's]].
====Setting up the PID's====
:1. To start we create a struct with all the necessary variables (code from ''pid.h''):
<blockquote>
<code>
<pre>
typedef struct
{
float desired; //< set point
float error; //< error
float prevError; //< previous error
float integ; //< integral
float deriv; //< derivative
float kp; //< proportional gain
float ki; //< integral gain
float kd; //< derivative gain
float outP; //< proportional output (debugging)
float outI; //< integral output (debugging)
float outD; //< derivative output (debugging)
float iLimit; //< integral limit
float iLimitLow; //< integral limit
float dt; //< delta-time dt
float angularLimit; //sets limit for how far Crazyflie can tip, to prevent flipping
float angularLimitLow; //^
float thrustLimit; //Sets upper limit for Thrust Output (60000?) **?
float thrustLimitLow; //Sets lower limit for thrust Output (10001)
} PidObject;
</pre>
</code>
</blockquote>
:2. To simplify scaling up the code to multiple Crazyflies, we will create a <code> ControllerObject </code> that contains multiple PID structs as shown (code in ''controller.h''):
<blockquote>
<code>
<pre>
typedef struct
{
PidObject pidRoll;
PidObject pidPitch;
PidObject pidYaw;
PidObject pidX;
PidObject pidY;
PidObject pidZ;
bool isInit;
} ControllerObject;
</pre>
</code>
</blockquote>
:3. Then we initialize the Objects to 0 at the start of each run (code in ''eris_vrpn.cpp''):
<blockquote>
<code>
<pre>
ControllerObject pidCtrl1 = { 0 }; // init all fields to zero
ControllerObject pidCtrl2 = { 0 }; // init all fields to zero
ControllerObject pidCtrl3 = { 0 }; // init all fields to zero
ControllerObject pidCtrl4 = { 0 }; // init all fields to zero
</pre>
</code>
</blockquote>
:4. Then populate the PidObjects with the desired parameters (code in ''pid.c''):
<blockquote>
<code>
<pre>
void pidInit(PidObject* pid, const float desired, const float kp,
const float ki, const float kd, const float dt)
{
pid->error = 0;
pid->prevError = 0;
pid->integ = 0;
pid->deriv = 0;
pid->desired = desired;
pid->kp = kp;
pid->ki = ki;
pid->kd = kd;
pid->iLimit = DEFAULT_PID_INTEGRATION_LIMIT;
pid->iLimitLow = -DEFAULT_PID_INTEGRATION_LIMIT;
pid->angularLimit = DEFAULT_PID_ANGLE_OUTPUT;
pid->angularLimitLow = -DEFAULT_PID_ANGLE_OUTPUT;
pid->thrustLimit = DEFAULT_PID_HIGH_THRUST_LIMIT;
pid->thrustLimitLow = DEFAULT_PID_LOW_THRUST_LIMIT;
pid->dt = dt;
}
</pre>
</code>
</blockquote>
Using the above function for each of the <code> PidObjects </code> inside of the <code> ControllerObject </code> below (code in ''controller.c''):
<blockquote>
<code>
<pre>
void controllerInit( ControllerObject * ctrl )
{
if(ctrl->isInit)
return;
pidInit(&ctrl->pidY, 0, PID_Y_KP, PID_Y_KI, PID_Y_KD, CAMERA_UPDATE_DT); //for Roll PID
pidInit(&ctrl->pidX, 0, PID_X_KP, PID_X_KI, PID_X_KD, CAMERA_UPDATE_DT); //for Pitch PID
pidInit(&ctrl->pidYaw, 0, PID_YAW_KP, PID_YAW_KI, PID_YAW_KD, CAMERA_UPDATE_DT);
pidInit(&ctrl->pidZ, 0, PID_Z_KP, PID_Z_KI, PID_Z_KD, CAMERA_UPDATE_DT);
pidSetIntegralLimit(&ctrl->pidY, PID_Y_INTEGRATION_LIMIT);
pidSetIntegralLimit(&ctrl->pidX, PID_X_INTEGRATION_LIMIT);
pidSetIntegralLimit(&ctrl->pidYaw, PID_YAW_INTEGRATION_LIMIT);
pidSetIntegralLimit(&ctrl->pidZ, PID_Z_INTEGRATION_LIMIT);
ctrl->isInit = true;
}
</pre>
</code>
</blockquote>
'''Note:'''If we have multiple Crazyflies we need a <code> ControllerObject </code> for each Crazyflie (code in ''eris_vrpn.cpp'')
<blockquote>
<code>
<pre>
controllerResetAllPID( &pidCtrl1 );
controllerInit( &pidCtrl1 );
#endif
#if NUM_QUADS >= 2
controllerResetAllPID( &pidCtrl2 );
controllerInit( &pidCtrl2 );
#endif
#if NUM_QUADS >=3
controllerResetAllPID( &pidCtrl3 );
controllerInit( &pidCtrl3 );
#endif
#if NUM_QUADS >=4
controllerResetAllPID( &pidCtrl4 );
controllerInit( &pidCtrl4 );
#endif
</pre>
</code>
</blockquote>
b3e45b4e9ad815e713c5480bee615b436048a27a
64
63
2016-07-13T17:43:55Z
Jnoronha
3
Finished PID calculation how-to
wikitext
text/x-wiki
The Crazyflie platform is completely customizable when it comes to the control design. As long as the controller can be written in C or C++, we can implement it in the Platform. This applies to both the controllers run on the PC Client and the controllers run on the Firmware of the Crazyflie. Originally the only controllers in the Platform were Firmware PID's that controlled the angular position and rates of the Crazyflie for hand flight. The original controller layout can be seen in '''Figure 1'''.
Below you will find documentation on the different types of Controllers that have been applied to the platform, organized by their location in the Platform.
== Firmware ==
=== Original PID Controllers (Angular Rotation) ===
Directly on the Crazyflie Firmware there are 5 PID controllers as seen here:
[[Image:FirmwareOnlyPIDArchitecture.png|500px]]
The Pitch and Roll angular position PID's receive constant setpoints from some outside source (gamepad controller or automated controller). The outputs of those angular position controllers is then fed into the angular rate controllers as shown. This final output is then fed into the Motor Command block which converts the angular rate setpoints into motor commands.
----
===State Estimator===
('''***NOT YET IMPLEMENTED***''')
Bitcraze is currently working on adding a state estimator onto the Firmware to handle control calculations instead of the PID.
The code is in place but the controller is not yet used as of '''7/13/16'''.
== PC Client ==
=== PID Controllers (Position and Yaw) ===
The first controller implemented on the Client were 4 PID controllers used to stabilize the Crazyflie's position in X, Y, and Z, as well as angular position in Yaw respectively. These PID's feed directly into the Firmware PID's as seen here:
[[Image:CompletePIDArchitectureFigure.png|500px]]
The controllers inside the red box are the original PID controllers located on the Firmware as shown above in the [[#Original PID Controllers (Angular Rotation)|Original PID's]].
====Initialize the PID's====
:1. To start we create a struct with all the necessary variables (code from ''pid.h''):
<blockquote>
<code>
<pre>
typedef struct
{
float desired; //< set point
float error; //< error
float prevError; //< previous error
float integ; //< integral
float deriv; //< derivative
float kp; //< proportional gain
float ki; //< integral gain
float kd; //< derivative gain
float outP; //< proportional output (debugging)
float outI; //< integral output (debugging)
float outD; //< derivative output (debugging)
float iLimit; //< integral limit
float iLimitLow; //< integral limit
float dt; //< delta-time dt
float angularLimit; //sets limit for how far Crazyflie can tip, to prevent flipping
float angularLimitLow; //^
float thrustLimit; //Sets upper limit for Thrust Output (60000?) **?
float thrustLimitLow; //Sets lower limit for thrust Output (10001)
} PidObject;
</pre>
</code>
</blockquote>
:2. To simplify scaling up the code to multiple Crazyflies, we will create a <code> ControllerObject </code> that contains multiple PID structs as shown (code in ''controller.h''):
<blockquote>
<code>
<pre>
typedef struct
{
PidObject pidRoll;
PidObject pidPitch;
PidObject pidYaw;
PidObject pidX;
PidObject pidY;
PidObject pidZ;
bool isInit;
} ControllerObject;
</pre>
</code>
</blockquote>
:3. Then we initialize the Objects to 0 at the start of each run (code in ''eris_vrpn.cpp''):
<blockquote>
<code>
<pre>
ControllerObject pidCtrl1 = { 0 }; // init all fields to zero
ControllerObject pidCtrl2 = { 0 }; // init all fields to zero
ControllerObject pidCtrl3 = { 0 }; // init all fields to zero
ControllerObject pidCtrl4 = { 0 }; // init all fields to zero
</pre>
</code>
</blockquote>
:4. Then populate the PidObjects with the desired parameters (code in ''pid.c''):
<blockquote>
<code>
<pre>
void pidInit(PidObject* pid, const float desired, const float kp,
const float ki, const float kd, const float dt)
{
pid->error = 0;
pid->prevError = 0;
pid->integ = 0;
pid->deriv = 0;
pid->desired = desired;
pid->kp = kp;
pid->ki = ki;
pid->kd = kd;
pid->iLimit = DEFAULT_PID_INTEGRATION_LIMIT;
pid->iLimitLow = -DEFAULT_PID_INTEGRATION_LIMIT;
pid->angularLimit = DEFAULT_PID_ANGLE_OUTPUT;
pid->angularLimitLow = -DEFAULT_PID_ANGLE_OUTPUT;
pid->thrustLimit = DEFAULT_PID_HIGH_THRUST_LIMIT;
pid->thrustLimitLow = DEFAULT_PID_LOW_THRUST_LIMIT;
pid->dt = dt;
}
</pre>
</code>
</blockquote>
Using the above function for each of the <code> PidObjects </code> inside of the <code> ControllerObject </code> below (code in ''controller.c''):
<blockquote>
<code>
<pre>
void controllerInit( ControllerObject * ctrl )
{
if(ctrl->isInit)
return;
pidInit(&ctrl->pidY, 0, PID_Y_KP, PID_Y_KI, PID_Y_KD, CAMERA_UPDATE_DT); //for Roll PID
pidInit(&ctrl->pidX, 0, PID_X_KP, PID_X_KI, PID_X_KD, CAMERA_UPDATE_DT); //for Pitch PID
pidInit(&ctrl->pidYaw, 0, PID_YAW_KP, PID_YAW_KI, PID_YAW_KD, CAMERA_UPDATE_DT);
pidInit(&ctrl->pidZ, 0, PID_Z_KP, PID_Z_KI, PID_Z_KD, CAMERA_UPDATE_DT);
pidSetIntegralLimit(&ctrl->pidY, PID_Y_INTEGRATION_LIMIT);
pidSetIntegralLimit(&ctrl->pidX, PID_X_INTEGRATION_LIMIT);
pidSetIntegralLimit(&ctrl->pidYaw, PID_YAW_INTEGRATION_LIMIT);
pidSetIntegralLimit(&ctrl->pidZ, PID_Z_INTEGRATION_LIMIT);
ctrl->isInit = true;
}
</pre>
</code>
</blockquote>
'''Note:'''If we have multiple Crazyflies we need a <code> ControllerObject </code> for each Crazyflie (code in ''eris_vrpn.cpp'')
<blockquote>
<code>
<pre>
controllerResetAllPID( &pidCtrl1 );
controllerInit( &pidCtrl1 );
#endif
#if NUM_QUADS >= 2
controllerResetAllPID( &pidCtrl2 );
controllerInit( &pidCtrl2 );
#endif
#if NUM_QUADS >=3
controllerResetAllPID( &pidCtrl3 );
controllerInit( &pidCtrl3 );
#endif
#if NUM_QUADS >=4
controllerResetAllPID( &pidCtrl4 );
controllerInit( &pidCtrl4 );
#endif
</pre>
</code>
</blockquote>
Now the initialization of the Controllers is complete.
====Calculating the PID's====
:1. Each loop we want to calculate the PID output (code in ''pid.c''):
<blockquote>
<code>
<pre>
float pidUpdateAngle(PidObject* pid, const float measured, const bool updateError) //**USED FOR ATTITUDE CONTROL
{
float output;
if(updateError)
{
pid->error = pid->desired - measured; //Calculates current error
}
pid->integ += pid->error * pid->dt; //Calculates integral term
if(pid->integ > pid->iLimit) //Checks that the integral term stays below the integral limit (anti-windup)
{
pid->integ = pid->iLimit;
}
else if(pid->integ < pid->iLimitLow)
{
pid->integ = pid->iLimitLow;
}
pid->deriv = (pid->error - pid->prevError) / pid->dt; //Calculates derivative term
pid->outP = pid->kp* pid->error;
pid->outI = pid->ki * pid->integ;
pid->outD = pid->kd * pid->deriv;
output = pid->outP + pid->outI + pid->outD; //Adds up all 3 calculated terms for output
if(output > pid->angularLimit) //Limits amount Crazyflie can tip
{
output = pid->angularLimit;
}
if(output < pid->angularLimitLow) //Limits amount Crazyflie can tip
{
output = pid->angularLimitLow;
}
pid->prevError = pid->error; //Stores the current error for next loop
return output;
}
</pre>
</code>
</blockquote>
'''Note:'''There are 3 different versions of this Function (for Angle, Thrust, and Yaw) since each has different output limits.
:2. Using the function above, combine all PID calculations into one function (code in ''controller.c''):
<blockquote>
<code>
<pre>
void controllerCorrectAttitudePID(ControllerObject * ctrl,
float xPositionActual, float yPositionActual, float zPositionActual, float eulerYawActual, float xPositionDesired, float yPositionDesired,
float zPositionDesired, float eulerYawDesired, float* rollControlOutput, float* pitchControlOutput, float* yawControlOutput, float* thrustControlOutput)
{
pidSetDesired(&ctrl->pidX, xPositionDesired);
*pitchControlOutput = pidUpdateAngle(&ctrl->pidX, xPositionActual, false); //Originally true
pidSetDesired(&ctrl->pidY, yPositionDesired);
*rollControlOutput = pidUpdateAngle(&ctrl->pidY, yPositionActual, false); //Originally true
pidSetDesired(&ctrl->pidZ, zPositionDesired);
*thrustControlOutput = pidUpdateThrust(&ctrl->pidZ,zPositionActual, true);
float yawError;
pidSetDesired(&ctrl->pidYaw, eulerYawDesired);
yawError = eulerYawDesired - eulerYawActual;
if(yawError > 180.0) //Ensures Yaw error stays between -180 and 180 degrees
yawError -= 360.0;
else if(yawError < -180.0)
yawError += 360.0;
pidSetError(&ctrl->pidYaw, yawError);
*yawControlOutput = pidUpdateYaw(&ctrl->pidYaw, eulerYawActual, true); //originally false
}
</pre>
</code>
</blockquote>
:3. In each Callback, calculate the Controller outputs, assigned to pointer values<code>*rollControlOutput</code>, <code>*pitchControlOutput</code>, etc... (code in ''eris_vrpn.cpp''):
<blockquote>
<code>
<pre>
xError1 = xPositionDesired1 - xPosition1;
yError1 = yPositionDesired1 - yPosition1; //Calculates error externally
controllerSetXYError(&pidCtrl1, xError1, yError1);
controllerCorrectAttitudePID(&pidCtrl1, t.pos[0], t.pos[1], zPosition1, correctedYaw1,
xPositionDesired1, yPositionDesired1, zPositionDesired1,
yawDesired1, &rollControlOutput1, &pitchControlOutput1,
&yawControlOutput1, &thrustControlOutput1);
</pre>
</code>
</blockquote>
'''Note:''' We calculate error externally for X and Y because certain swarm controllers need special setpoint modifiers (this way we can switch modes without effecting the default setpoint):
'''Example:''' Follow Hand Mode Error (Crazyflie1 will have setpoint -0.5 m lower in X and +0.5 m higher in Y than your hand trackable):
<blockquote>
<code>
<pre>
...
xError1 = (xPositionHand - 0.5) - xPosition1;
yError1 = (yPositionHand + 0.5) - yPosition1;
controllerSetXYError(&pidCtrl1, xError1, yError1);
...
</pre>
</code>
</blockquote>
:4. Repeat for each set of new location data.
2b08acf4f7d47367e1ddb164fb3ec1aa50257cb4
65
64
2016-07-13T17:45:54Z
Jnoronha
3
Fixed formatting on the notes
wikitext
text/x-wiki
The Crazyflie platform is completely customizable when it comes to the control design. As long as the controller can be written in C or C++, we can implement it in the Platform. This applies to both the controllers run on the PC Client and the controllers run on the Firmware of the Crazyflie. Originally the only controllers in the Platform were Firmware PID's that controlled the angular position and rates of the Crazyflie for hand flight. The original controller layout can be seen in '''Figure 1'''.
Below you will find documentation on the different types of Controllers that have been applied to the platform, organized by their location in the Platform.
== Firmware ==
=== Original PID Controllers (Angular Rotation) ===
Directly on the Crazyflie Firmware there are 5 PID controllers as seen here:
[[Image:FirmwareOnlyPIDArchitecture.png|500px]]
The Pitch and Roll angular position PID's receive constant setpoints from some outside source (gamepad controller or automated controller). The outputs of those angular position controllers is then fed into the angular rate controllers as shown. This final output is then fed into the Motor Command block which converts the angular rate setpoints into motor commands.
----
===State Estimator===
('''***NOT YET IMPLEMENTED***''')
Bitcraze is currently working on adding a state estimator onto the Firmware to handle control calculations instead of the PID.
The code is in place but the controller is not yet used as of '''7/13/16'''.
== PC Client ==
=== PID Controllers (Position and Yaw) ===
The first controller implemented on the Client were 4 PID controllers used to stabilize the Crazyflie's position in X, Y, and Z, as well as angular position in Yaw respectively. These PID's feed directly into the Firmware PID's as seen here:
[[Image:CompletePIDArchitectureFigure.png|500px]]
The controllers inside the red box are the original PID controllers located on the Firmware as shown above in the [[#Original PID Controllers (Angular Rotation)|Original PID's]].
====Initialize the PID's====
:1. To start we create a struct with all the necessary variables (code from ''pid.h''):
<blockquote>
<code>
<pre>
typedef struct
{
float desired; //< set point
float error; //< error
float prevError; //< previous error
float integ; //< integral
float deriv; //< derivative
float kp; //< proportional gain
float ki; //< integral gain
float kd; //< derivative gain
float outP; //< proportional output (debugging)
float outI; //< integral output (debugging)
float outD; //< derivative output (debugging)
float iLimit; //< integral limit
float iLimitLow; //< integral limit
float dt; //< delta-time dt
float angularLimit; //sets limit for how far Crazyflie can tip, to prevent flipping
float angularLimitLow; //^
float thrustLimit; //Sets upper limit for Thrust Output (60000?) **?
float thrustLimitLow; //Sets lower limit for thrust Output (10001)
} PidObject;
</pre>
</code>
</blockquote>
:2. To simplify scaling up the code to multiple Crazyflies, we will create a <code> ControllerObject </code> that contains multiple PID structs as shown (code in ''controller.h''):
<blockquote>
<code>
<pre>
typedef struct
{
PidObject pidRoll;
PidObject pidPitch;
PidObject pidYaw;
PidObject pidX;
PidObject pidY;
PidObject pidZ;
bool isInit;
} ControllerObject;
</pre>
</code>
</blockquote>
:3. Then we initialize the Objects to 0 at the start of each run (code in ''eris_vrpn.cpp''):
<blockquote>
<code>
<pre>
ControllerObject pidCtrl1 = { 0 }; // init all fields to zero
ControllerObject pidCtrl2 = { 0 }; // init all fields to zero
ControllerObject pidCtrl3 = { 0 }; // init all fields to zero
ControllerObject pidCtrl4 = { 0 }; // init all fields to zero
</pre>
</code>
</blockquote>
:4. Then populate the PidObjects with the desired parameters (code in ''pid.c''):
<blockquote>
<code>
<pre>
void pidInit(PidObject* pid, const float desired, const float kp,
const float ki, const float kd, const float dt)
{
pid->error = 0;
pid->prevError = 0;
pid->integ = 0;
pid->deriv = 0;
pid->desired = desired;
pid->kp = kp;
pid->ki = ki;
pid->kd = kd;
pid->iLimit = DEFAULT_PID_INTEGRATION_LIMIT;
pid->iLimitLow = -DEFAULT_PID_INTEGRATION_LIMIT;
pid->angularLimit = DEFAULT_PID_ANGLE_OUTPUT;
pid->angularLimitLow = -DEFAULT_PID_ANGLE_OUTPUT;
pid->thrustLimit = DEFAULT_PID_HIGH_THRUST_LIMIT;
pid->thrustLimitLow = DEFAULT_PID_LOW_THRUST_LIMIT;
pid->dt = dt;
}
</pre>
</code>
</blockquote>
Using the above function for each of the <code>PidObjects</code> inside of the <code>ControllerObject</code> below (code in ''controller.c''):
<blockquote>
<code>
<pre>
void controllerInit( ControllerObject * ctrl )
{
if(ctrl->isInit)
return;
pidInit(&ctrl->pidY, 0, PID_Y_KP, PID_Y_KI, PID_Y_KD, CAMERA_UPDATE_DT); //for Roll PID
pidInit(&ctrl->pidX, 0, PID_X_KP, PID_X_KI, PID_X_KD, CAMERA_UPDATE_DT); //for Pitch PID
pidInit(&ctrl->pidYaw, 0, PID_YAW_KP, PID_YAW_KI, PID_YAW_KD, CAMERA_UPDATE_DT);
pidInit(&ctrl->pidZ, 0, PID_Z_KP, PID_Z_KI, PID_Z_KD, CAMERA_UPDATE_DT);
pidSetIntegralLimit(&ctrl->pidY, PID_Y_INTEGRATION_LIMIT);
pidSetIntegralLimit(&ctrl->pidX, PID_X_INTEGRATION_LIMIT);
pidSetIntegralLimit(&ctrl->pidYaw, PID_YAW_INTEGRATION_LIMIT);
pidSetIntegralLimit(&ctrl->pidZ, PID_Z_INTEGRATION_LIMIT);
ctrl->isInit = true;
}
</pre>
</code>
</blockquote>
'''Note:''' If we have multiple Crazyflies we need a <code>ControllerObject</code> for each Crazyflie (code in ''eris_vrpn.cpp'')
<blockquote>
<code>
<pre>
controllerResetAllPID( &pidCtrl1 );
controllerInit( &pidCtrl1 );
#endif
#if NUM_QUADS >= 2
controllerResetAllPID( &pidCtrl2 );
controllerInit( &pidCtrl2 );
#endif
#if NUM_QUADS >=3
controllerResetAllPID( &pidCtrl3 );
controllerInit( &pidCtrl3 );
#endif
#if NUM_QUADS >=4
controllerResetAllPID( &pidCtrl4 );
controllerInit( &pidCtrl4 );
#endif
</pre>
</code>
</blockquote>
Now the initialization of the Controllers is complete.
====Calculating the PID's====
:1. Each loop we want to calculate the PID output (code in ''pid.c''):
<blockquote>
<code>
<pre>
float pidUpdateAngle(PidObject* pid, const float measured, const bool updateError) //**USED FOR ATTITUDE CONTROL
{
float output;
if(updateError)
{
pid->error = pid->desired - measured; //Calculates current error
}
pid->integ += pid->error * pid->dt; //Calculates integral term
if(pid->integ > pid->iLimit) //Checks that the integral term stays below the integral limit (anti-windup)
{
pid->integ = pid->iLimit;
}
else if(pid->integ < pid->iLimitLow)
{
pid->integ = pid->iLimitLow;
}
pid->deriv = (pid->error - pid->prevError) / pid->dt; //Calculates derivative term
pid->outP = pid->kp* pid->error;
pid->outI = pid->ki * pid->integ;
pid->outD = pid->kd * pid->deriv;
output = pid->outP + pid->outI + pid->outD; //Adds up all 3 calculated terms for output
if(output > pid->angularLimit) //Limits amount Crazyflie can tip
{
output = pid->angularLimit;
}
if(output < pid->angularLimitLow) //Limits amount Crazyflie can tip
{
output = pid->angularLimitLow;
}
pid->prevError = pid->error; //Stores the current error for next loop
return output;
}
</pre>
</code>
</blockquote>
'''Note:''' There are 3 different versions of this Function (for Angle, Thrust, and Yaw) since each has different output limits.
:2. Using the function above, combine all PID calculations into one function (code in ''controller.c''):
<blockquote>
<code>
<pre>
void controllerCorrectAttitudePID(ControllerObject * ctrl,
float xPositionActual, float yPositionActual, float zPositionActual, float eulerYawActual, float xPositionDesired, float yPositionDesired,
float zPositionDesired, float eulerYawDesired, float* rollControlOutput, float* pitchControlOutput, float* yawControlOutput, float* thrustControlOutput)
{
pidSetDesired(&ctrl->pidX, xPositionDesired);
*pitchControlOutput = pidUpdateAngle(&ctrl->pidX, xPositionActual, false); //Originally true
pidSetDesired(&ctrl->pidY, yPositionDesired);
*rollControlOutput = pidUpdateAngle(&ctrl->pidY, yPositionActual, false); //Originally true
pidSetDesired(&ctrl->pidZ, zPositionDesired);
*thrustControlOutput = pidUpdateThrust(&ctrl->pidZ,zPositionActual, true);
float yawError;
pidSetDesired(&ctrl->pidYaw, eulerYawDesired);
yawError = eulerYawDesired - eulerYawActual;
if(yawError > 180.0) //Ensures Yaw error stays between -180 and 180 degrees
yawError -= 360.0;
else if(yawError < -180.0)
yawError += 360.0;
pidSetError(&ctrl->pidYaw, yawError);
*yawControlOutput = pidUpdateYaw(&ctrl->pidYaw, eulerYawActual, true); //originally false
}
</pre>
</code>
</blockquote>
:3. In each Callback, calculate the Controller outputs, assigned to pointer values<code>*rollControlOutput</code>, <code>*pitchControlOutput</code>, etc... (code in ''eris_vrpn.cpp''):
<blockquote>
<code>
<pre>
xError1 = xPositionDesired1 - xPosition1;
yError1 = yPositionDesired1 - yPosition1; //Calculates error externally
controllerSetXYError(&pidCtrl1, xError1, yError1);
controllerCorrectAttitudePID(&pidCtrl1, t.pos[0], t.pos[1], zPosition1, correctedYaw1,
xPositionDesired1, yPositionDesired1, zPositionDesired1,
yawDesired1, &rollControlOutput1, &pitchControlOutput1,
&yawControlOutput1, &thrustControlOutput1);
</pre>
</code>
</blockquote>
'''Note:''' We calculate error externally for X and Y because certain swarm controllers need special setpoint modifiers (this way we can switch modes without effecting the default setpoint):
'''Example:''' Follow Hand Mode Error (Crazyflie1 will have setpoint -0.5 m lower in X and +0.5 m higher in Y than your hand trackable):
<blockquote>
<code>
<pre>
...
xError1 = (xPositionHand - 0.5) - xPosition1;
yError1 = (yPositionHand + 0.5) - yPosition1;
controllerSetXYError(&pidCtrl1, xError1, yError1);
...
</pre>
</code>
</blockquote>
:4. Repeat for each set of new location data.
097552286225855ba1806eeae56521bd0223ec5d
66
65
2016-07-13T17:46:50Z
Jnoronha
3
wikitext
text/x-wiki
The Crazyflie platform is completely customizable when it comes to the control design. As long as the controller can be written in C or C++, we can implement it in the Platform. This applies to both the controllers run on the PC Client and the controllers run on the Firmware of the Crazyflie. Originally the only controllers in the Platform were Firmware PID's that controlled the angular position and rates of the Crazyflie for hand flight. The original controller layout can be seen in '''Figure 1'''.
Below you will find documentation on the different types of Controllers that have been applied to the platform, organized by their location in the Platform.
== Firmware ==
=== Original PID Controllers (Angular Rotation) ===
Directly on the Crazyflie Firmware there are 5 PID controllers as seen here:
[[Image:FirmwareOnlyPIDArchitecture.png|500px]]
The Pitch and Roll angular position PID's receive constant setpoints from some outside source (gamepad controller or automated controller). The outputs of those angular position controllers is then fed into the angular rate controllers as shown. This final output is then fed into the Motor Command block which converts the angular rate setpoints into motor commands.
----
===State Estimator===
('''***NOT YET IMPLEMENTED***''')
Bitcraze is currently working on adding a state estimator onto the Firmware to handle control calculations instead of the PID.
The code is in place but the controller is not yet used as of '''7/13/16'''.
== PC Client ==
=== PID Controllers (Position and Yaw) ===
The first controller implemented on the Client were 4 PID controllers used to stabilize the Crazyflie's position in X, Y, and Z, and angular position in Yaw respectively. These PID's feed directly into the Firmware PID's as seen here:
[[Image:CompletePIDArchitectureFigure.png|500px]]
The controllers inside the red box are the original PID controllers located on the Firmware as shown above in the [[#Original PID Controllers (Angular Rotation)|Original PID's]].
====Initialize the PID's====
:1. To start we create a struct with all the necessary variables (code from ''pid.h''):
<blockquote>
<code>
<pre>
typedef struct
{
float desired; //< set point
float error; //< error
float prevError; //< previous error
float integ; //< integral
float deriv; //< derivative
float kp; //< proportional gain
float ki; //< integral gain
float kd; //< derivative gain
float outP; //< proportional output (debugging)
float outI; //< integral output (debugging)
float outD; //< derivative output (debugging)
float iLimit; //< integral limit
float iLimitLow; //< integral limit
float dt; //< delta-time dt
float angularLimit; //sets limit for how far Crazyflie can tip, to prevent flipping
float angularLimitLow; //^
float thrustLimit; //Sets upper limit for Thrust Output (60000?) **?
float thrustLimitLow; //Sets lower limit for thrust Output (10001)
} PidObject;
</pre>
</code>
</blockquote>
:2. To simplify scaling up the code to multiple Crazyflies, we will create a <code> ControllerObject </code> that contains multiple PID structs as shown (code in ''controller.h''):
<blockquote>
<code>
<pre>
typedef struct
{
PidObject pidRoll;
PidObject pidPitch;
PidObject pidYaw;
PidObject pidX;
PidObject pidY;
PidObject pidZ;
bool isInit;
} ControllerObject;
</pre>
</code>
</blockquote>
:3. Then we initialize the Objects to 0 at the start of each run (code in ''eris_vrpn.cpp''):
<blockquote>
<code>
<pre>
ControllerObject pidCtrl1 = { 0 }; // init all fields to zero
ControllerObject pidCtrl2 = { 0 }; // init all fields to zero
ControllerObject pidCtrl3 = { 0 }; // init all fields to zero
ControllerObject pidCtrl4 = { 0 }; // init all fields to zero
</pre>
</code>
</blockquote>
:4. Then populate the PidObjects with the desired parameters (code in ''pid.c''):
<blockquote>
<code>
<pre>
void pidInit(PidObject* pid, const float desired, const float kp,
const float ki, const float kd, const float dt)
{
pid->error = 0;
pid->prevError = 0;
pid->integ = 0;
pid->deriv = 0;
pid->desired = desired;
pid->kp = kp;
pid->ki = ki;
pid->kd = kd;
pid->iLimit = DEFAULT_PID_INTEGRATION_LIMIT;
pid->iLimitLow = -DEFAULT_PID_INTEGRATION_LIMIT;
pid->angularLimit = DEFAULT_PID_ANGLE_OUTPUT;
pid->angularLimitLow = -DEFAULT_PID_ANGLE_OUTPUT;
pid->thrustLimit = DEFAULT_PID_HIGH_THRUST_LIMIT;
pid->thrustLimitLow = DEFAULT_PID_LOW_THRUST_LIMIT;
pid->dt = dt;
}
</pre>
</code>
</blockquote>
Using the above function for each of the <code>PidObjects</code> inside of the <code>ControllerObject</code> below (code in ''controller.c''):
<blockquote>
<code>
<pre>
void controllerInit( ControllerObject * ctrl )
{
if(ctrl->isInit)
return;
pidInit(&ctrl->pidY, 0, PID_Y_KP, PID_Y_KI, PID_Y_KD, CAMERA_UPDATE_DT); //for Roll PID
pidInit(&ctrl->pidX, 0, PID_X_KP, PID_X_KI, PID_X_KD, CAMERA_UPDATE_DT); //for Pitch PID
pidInit(&ctrl->pidYaw, 0, PID_YAW_KP, PID_YAW_KI, PID_YAW_KD, CAMERA_UPDATE_DT);
pidInit(&ctrl->pidZ, 0, PID_Z_KP, PID_Z_KI, PID_Z_KD, CAMERA_UPDATE_DT);
pidSetIntegralLimit(&ctrl->pidY, PID_Y_INTEGRATION_LIMIT);
pidSetIntegralLimit(&ctrl->pidX, PID_X_INTEGRATION_LIMIT);
pidSetIntegralLimit(&ctrl->pidYaw, PID_YAW_INTEGRATION_LIMIT);
pidSetIntegralLimit(&ctrl->pidZ, PID_Z_INTEGRATION_LIMIT);
ctrl->isInit = true;
}
</pre>
</code>
</blockquote>
'''Note:''' If we have multiple Crazyflies we need a <code>ControllerObject</code> for each Crazyflie (code in ''eris_vrpn.cpp'')
<blockquote>
<code>
<pre>
controllerResetAllPID( &pidCtrl1 );
controllerInit( &pidCtrl1 );
#endif
#if NUM_QUADS >= 2
controllerResetAllPID( &pidCtrl2 );
controllerInit( &pidCtrl2 );
#endif
#if NUM_QUADS >=3
controllerResetAllPID( &pidCtrl3 );
controllerInit( &pidCtrl3 );
#endif
#if NUM_QUADS >=4
controllerResetAllPID( &pidCtrl4 );
controllerInit( &pidCtrl4 );
#endif
</pre>
</code>
</blockquote>
Now the initialization of the Controllers is complete.
====Calculating the PID's====
:1. Each loop we want to calculate the PID output (code in ''pid.c''):
<blockquote>
<code>
<pre>
float pidUpdateAngle(PidObject* pid, const float measured, const bool updateError) //**USED FOR ATTITUDE CONTROL
{
float output;
if(updateError)
{
pid->error = pid->desired - measured; //Calculates current error
}
pid->integ += pid->error * pid->dt; //Calculates integral term
if(pid->integ > pid->iLimit) //Checks that the integral term stays below the integral limit (anti-windup)
{
pid->integ = pid->iLimit;
}
else if(pid->integ < pid->iLimitLow)
{
pid->integ = pid->iLimitLow;
}
pid->deriv = (pid->error - pid->prevError) / pid->dt; //Calculates derivative term
pid->outP = pid->kp* pid->error;
pid->outI = pid->ki * pid->integ;
pid->outD = pid->kd * pid->deriv;
output = pid->outP + pid->outI + pid->outD; //Adds up all 3 calculated terms for output
if(output > pid->angularLimit) //Limits amount Crazyflie can tip
{
output = pid->angularLimit;
}
if(output < pid->angularLimitLow) //Limits amount Crazyflie can tip
{
output = pid->angularLimitLow;
}
pid->prevError = pid->error; //Stores the current error for next loop
return output;
}
</pre>
</code>
</blockquote>
'''Note:''' There are 3 different versions of this Function (for Angle, Thrust, and Yaw) since each has different output limits.
:2. Using the function above, combine all PID calculations into one function (code in ''controller.c''):
<blockquote>
<code>
<pre>
void controllerCorrectAttitudePID(ControllerObject * ctrl,
float xPositionActual, float yPositionActual, float zPositionActual, float eulerYawActual, float xPositionDesired, float yPositionDesired,
float zPositionDesired, float eulerYawDesired, float* rollControlOutput, float* pitchControlOutput, float* yawControlOutput, float* thrustControlOutput)
{
pidSetDesired(&ctrl->pidX, xPositionDesired);
*pitchControlOutput = pidUpdateAngle(&ctrl->pidX, xPositionActual, false); //Originally true
pidSetDesired(&ctrl->pidY, yPositionDesired);
*rollControlOutput = pidUpdateAngle(&ctrl->pidY, yPositionActual, false); //Originally true
pidSetDesired(&ctrl->pidZ, zPositionDesired);
*thrustControlOutput = pidUpdateThrust(&ctrl->pidZ,zPositionActual, true);
float yawError;
pidSetDesired(&ctrl->pidYaw, eulerYawDesired);
yawError = eulerYawDesired - eulerYawActual;
if(yawError > 180.0) //Ensures Yaw error stays between -180 and 180 degrees
yawError -= 360.0;
else if(yawError < -180.0)
yawError += 360.0;
pidSetError(&ctrl->pidYaw, yawError);
*yawControlOutput = pidUpdateYaw(&ctrl->pidYaw, eulerYawActual, true); //originally false
}
</pre>
</code>
</blockquote>
:3. In each Callback, calculate the Controller outputs, assigned to pointer values<code>*rollControlOutput</code>, <code>*pitchControlOutput</code>, etc... (code in ''eris_vrpn.cpp''):
<blockquote>
<code>
<pre>
xError1 = xPositionDesired1 - xPosition1;
yError1 = yPositionDesired1 - yPosition1; //Calculates error externally
controllerSetXYError(&pidCtrl1, xError1, yError1);
controllerCorrectAttitudePID(&pidCtrl1, t.pos[0], t.pos[1], zPosition1, correctedYaw1,
xPositionDesired1, yPositionDesired1, zPositionDesired1,
yawDesired1, &rollControlOutput1, &pitchControlOutput1,
&yawControlOutput1, &thrustControlOutput1);
</pre>
</code>
</blockquote>
'''Note:''' We calculate error externally for X and Y because certain swarm controllers need special setpoint modifiers (this way we can switch modes without effecting the default setpoint):
'''Example:''' Follow Hand Mode Error (Crazyflie1 will have setpoint -0.5 m lower in X and +0.5 m higher in Y than your hand trackable):
<blockquote>
<code>
<pre>
...
xError1 = (xPositionHand - 0.5) - xPosition1;
yError1 = (yPositionHand + 0.5) - yPosition1;
controllerSetXYError(&pidCtrl1, xError1, yError1);
...
</pre>
</code>
</blockquote>
:4. Repeat for each set of new location data.
9de61c4ba3883cb9a7913c4ddd2e2d251ff75a7f
67
66
2016-07-13T17:48:10Z
Jnoronha
3
Replaced figure 1 link with Original PID's header link
wikitext
text/x-wiki
The Crazyflie platform is completely customizable when it comes to the control design. As long as the controller can be written in C or C++, we can implement it in the Platform. This applies to both the controllers run on the PC Client and the controllers run on the Firmware of the Crazyflie. Originally the only controllers in the Platform were Firmware PID's that controlled the angular position and rates of the Crazyflie for hand flight. The original controller layout can be seen here [[#Original PID Controllers (Angular Rotation)|Original PID's]].
Below you will find documentation on the different types of Controllers that have been applied to the platform, organized by their location in the Platform.
== Firmware ==
=== Original PID Controllers (Angular Rotation) ===
Directly on the Crazyflie Firmware there are 5 PID controllers as seen here:
[[Image:FirmwareOnlyPIDArchitecture.png|500px]]
The Pitch and Roll angular position PID's receive constant setpoints from some outside source (gamepad controller or automated controller). The outputs of those angular position controllers is then fed into the angular rate controllers as shown. This final output is then fed into the Motor Command block which converts the angular rate setpoints into motor commands.
----
===State Estimator===
('''***NOT YET IMPLEMENTED***''')
Bitcraze is currently working on adding a state estimator onto the Firmware to handle control calculations instead of the PID.
The code is in place but the controller is not yet used as of '''7/13/16'''.
== PC Client ==
=== PID Controllers (Position and Yaw) ===
The first controller implemented on the Client were 4 PID controllers used to stabilize the Crazyflie's position in X, Y, and Z, and angular position in Yaw respectively. These PID's feed directly into the Firmware PID's as seen here:
[[Image:CompletePIDArchitectureFigure.png|500px]]
The controllers inside the red box are the original PID controllers located on the Firmware as shown above in the [[#Original PID Controllers (Angular Rotation)|Original PID's]].
====Initialize the PID's====
:1. To start we create a struct with all the necessary variables (code from ''pid.h''):
<blockquote>
<code>
<pre>
typedef struct
{
float desired; //< set point
float error; //< error
float prevError; //< previous error
float integ; //< integral
float deriv; //< derivative
float kp; //< proportional gain
float ki; //< integral gain
float kd; //< derivative gain
float outP; //< proportional output (debugging)
float outI; //< integral output (debugging)
float outD; //< derivative output (debugging)
float iLimit; //< integral limit
float iLimitLow; //< integral limit
float dt; //< delta-time dt
float angularLimit; //sets limit for how far Crazyflie can tip, to prevent flipping
float angularLimitLow; //^
float thrustLimit; //Sets upper limit for Thrust Output (60000?) **?
float thrustLimitLow; //Sets lower limit for thrust Output (10001)
} PidObject;
</pre>
</code>
</blockquote>
:2. To simplify scaling up the code to multiple Crazyflies, we will create a <code> ControllerObject </code> that contains multiple PID structs as shown (code in ''controller.h''):
<blockquote>
<code>
<pre>
typedef struct
{
PidObject pidRoll;
PidObject pidPitch;
PidObject pidYaw;
PidObject pidX;
PidObject pidY;
PidObject pidZ;
bool isInit;
} ControllerObject;
</pre>
</code>
</blockquote>
:3. Then we initialize the Objects to 0 at the start of each run (code in ''eris_vrpn.cpp''):
<blockquote>
<code>
<pre>
ControllerObject pidCtrl1 = { 0 }; // init all fields to zero
ControllerObject pidCtrl2 = { 0 }; // init all fields to zero
ControllerObject pidCtrl3 = { 0 }; // init all fields to zero
ControllerObject pidCtrl4 = { 0 }; // init all fields to zero
</pre>
</code>
</blockquote>
:4. Then populate the PidObjects with the desired parameters (code in ''pid.c''):
<blockquote>
<code>
<pre>
void pidInit(PidObject* pid, const float desired, const float kp,
const float ki, const float kd, const float dt)
{
pid->error = 0;
pid->prevError = 0;
pid->integ = 0;
pid->deriv = 0;
pid->desired = desired;
pid->kp = kp;
pid->ki = ki;
pid->kd = kd;
pid->iLimit = DEFAULT_PID_INTEGRATION_LIMIT;
pid->iLimitLow = -DEFAULT_PID_INTEGRATION_LIMIT;
pid->angularLimit = DEFAULT_PID_ANGLE_OUTPUT;
pid->angularLimitLow = -DEFAULT_PID_ANGLE_OUTPUT;
pid->thrustLimit = DEFAULT_PID_HIGH_THRUST_LIMIT;
pid->thrustLimitLow = DEFAULT_PID_LOW_THRUST_LIMIT;
pid->dt = dt;
}
</pre>
</code>
</blockquote>
Using the above function for each of the <code>PidObjects</code> inside of the <code>ControllerObject</code> below (code in ''controller.c''):
<blockquote>
<code>
<pre>
void controllerInit( ControllerObject * ctrl )
{
if(ctrl->isInit)
return;
pidInit(&ctrl->pidY, 0, PID_Y_KP, PID_Y_KI, PID_Y_KD, CAMERA_UPDATE_DT); //for Roll PID
pidInit(&ctrl->pidX, 0, PID_X_KP, PID_X_KI, PID_X_KD, CAMERA_UPDATE_DT); //for Pitch PID
pidInit(&ctrl->pidYaw, 0, PID_YAW_KP, PID_YAW_KI, PID_YAW_KD, CAMERA_UPDATE_DT);
pidInit(&ctrl->pidZ, 0, PID_Z_KP, PID_Z_KI, PID_Z_KD, CAMERA_UPDATE_DT);
pidSetIntegralLimit(&ctrl->pidY, PID_Y_INTEGRATION_LIMIT);
pidSetIntegralLimit(&ctrl->pidX, PID_X_INTEGRATION_LIMIT);
pidSetIntegralLimit(&ctrl->pidYaw, PID_YAW_INTEGRATION_LIMIT);
pidSetIntegralLimit(&ctrl->pidZ, PID_Z_INTEGRATION_LIMIT);
ctrl->isInit = true;
}
</pre>
</code>
</blockquote>
'''Note:''' If we have multiple Crazyflies we need a <code>ControllerObject</code> for each Crazyflie (code in ''eris_vrpn.cpp'')
<blockquote>
<code>
<pre>
controllerResetAllPID( &pidCtrl1 );
controllerInit( &pidCtrl1 );
#endif
#if NUM_QUADS >= 2
controllerResetAllPID( &pidCtrl2 );
controllerInit( &pidCtrl2 );
#endif
#if NUM_QUADS >=3
controllerResetAllPID( &pidCtrl3 );
controllerInit( &pidCtrl3 );
#endif
#if NUM_QUADS >=4
controllerResetAllPID( &pidCtrl4 );
controllerInit( &pidCtrl4 );
#endif
</pre>
</code>
</blockquote>
Now the initialization of the Controllers is complete.
====Calculating the PID's====
:1. Each loop we want to calculate the PID output (code in ''pid.c''):
<blockquote>
<code>
<pre>
float pidUpdateAngle(PidObject* pid, const float measured, const bool updateError) //**USED FOR ATTITUDE CONTROL
{
float output;
if(updateError)
{
pid->error = pid->desired - measured; //Calculates current error
}
pid->integ += pid->error * pid->dt; //Calculates integral term
if(pid->integ > pid->iLimit) //Checks that the integral term stays below the integral limit (anti-windup)
{
pid->integ = pid->iLimit;
}
else if(pid->integ < pid->iLimitLow)
{
pid->integ = pid->iLimitLow;
}
pid->deriv = (pid->error - pid->prevError) / pid->dt; //Calculates derivative term
pid->outP = pid->kp* pid->error;
pid->outI = pid->ki * pid->integ;
pid->outD = pid->kd * pid->deriv;
output = pid->outP + pid->outI + pid->outD; //Adds up all 3 calculated terms for output
if(output > pid->angularLimit) //Limits amount Crazyflie can tip
{
output = pid->angularLimit;
}
if(output < pid->angularLimitLow) //Limits amount Crazyflie can tip
{
output = pid->angularLimitLow;
}
pid->prevError = pid->error; //Stores the current error for next loop
return output;
}
</pre>
</code>
</blockquote>
'''Note:''' There are 3 different versions of this Function (for Angle, Thrust, and Yaw) since each has different output limits.
:2. Using the function above, combine all PID calculations into one function (code in ''controller.c''):
<blockquote>
<code>
<pre>
void controllerCorrectAttitudePID(ControllerObject * ctrl,
float xPositionActual, float yPositionActual, float zPositionActual, float eulerYawActual, float xPositionDesired, float yPositionDesired,
float zPositionDesired, float eulerYawDesired, float* rollControlOutput, float* pitchControlOutput, float* yawControlOutput, float* thrustControlOutput)
{
pidSetDesired(&ctrl->pidX, xPositionDesired);
*pitchControlOutput = pidUpdateAngle(&ctrl->pidX, xPositionActual, false); //Originally true
pidSetDesired(&ctrl->pidY, yPositionDesired);
*rollControlOutput = pidUpdateAngle(&ctrl->pidY, yPositionActual, false); //Originally true
pidSetDesired(&ctrl->pidZ, zPositionDesired);
*thrustControlOutput = pidUpdateThrust(&ctrl->pidZ,zPositionActual, true);
float yawError;
pidSetDesired(&ctrl->pidYaw, eulerYawDesired);
yawError = eulerYawDesired - eulerYawActual;
if(yawError > 180.0) //Ensures Yaw error stays between -180 and 180 degrees
yawError -= 360.0;
else if(yawError < -180.0)
yawError += 360.0;
pidSetError(&ctrl->pidYaw, yawError);
*yawControlOutput = pidUpdateYaw(&ctrl->pidYaw, eulerYawActual, true); //originally false
}
</pre>
</code>
</blockquote>
:3. In each Callback, calculate the Controller outputs, assigned to pointer values<code>*rollControlOutput</code>, <code>*pitchControlOutput</code>, etc... (code in ''eris_vrpn.cpp''):
<blockquote>
<code>
<pre>
xError1 = xPositionDesired1 - xPosition1;
yError1 = yPositionDesired1 - yPosition1; //Calculates error externally
controllerSetXYError(&pidCtrl1, xError1, yError1);
controllerCorrectAttitudePID(&pidCtrl1, t.pos[0], t.pos[1], zPosition1, correctedYaw1,
xPositionDesired1, yPositionDesired1, zPositionDesired1,
yawDesired1, &rollControlOutput1, &pitchControlOutput1,
&yawControlOutput1, &thrustControlOutput1);
</pre>
</code>
</blockquote>
'''Note:''' We calculate error externally for X and Y because certain swarm controllers need special setpoint modifiers (this way we can switch modes without effecting the default setpoint):
'''Example:''' Follow Hand Mode Error (Crazyflie1 will have setpoint -0.5 m lower in X and +0.5 m higher in Y than your hand trackable):
<blockquote>
<code>
<pre>
...
xError1 = (xPositionHand - 0.5) - xPosition1;
yError1 = (yPositionHand + 0.5) - yPosition1;
controllerSetXYError(&pidCtrl1, xError1, yError1);
...
</pre>
</code>
</blockquote>
:4. Repeat for each set of new location data.
1e1f42f0310ed1276e37432b6aa87216f52d121b
68
67
2016-07-13T18:06:26Z
Jnoronha
3
Finally figured out sub-section linking for the Directory footer
wikitext
text/x-wiki
The Crazyflie platform is completely customizable when it comes to the control design. As long as the controller can be written in C or C++, we can implement it in the Platform. This applies to both the controllers run on the PC Client and the controllers run on the Firmware of the Crazyflie. Originally the only controllers in the Platform were Firmware PID's that controlled the angular position and rates of the Crazyflie for hand flight. The original controller layout can be seen here [[#Original PID Controllers (Angular Rotation)|Original PID's]].
Below you will find documentation on the different types of Controllers that have been applied to the platform, organized by their location in the Platform.
== Firmware ==
=== Original PID Controllers (Angular Rotation) ===
Directly on the Crazyflie Firmware there are 5 PID controllers as seen here:
[[Image:FirmwareOnlyPIDArchitecture.png|500px]]
The Pitch and Roll angular position PID's receive constant setpoints from some outside source (gamepad controller or automated controller). The outputs of those angular position controllers is then fed into the angular rate controllers as shown. This final output is then fed into the Motor Command block which converts the angular rate setpoints into motor commands.
----
===State Estimator===
('''***NOT YET IMPLEMENTED***''')
Bitcraze is currently working on adding a state estimator onto the Firmware to handle control calculations instead of the PID.
The code is in place but the controller is not yet used as of '''7/13/16'''.
== PC Client ==
=== PID Controllers (Position and Yaw) ===
The first controller implemented on the Client were 4 PID controllers used to stabilize the Crazyflie's position in X, Y, and Z, and angular position in Yaw respectively. These PID's feed directly into the Firmware PID's as seen here:
[[Image:CompletePIDArchitectureFigure.png|500px]]
The controllers inside the red box are the original PID controllers located on the Firmware as shown above in the [[#Original PID Controllers (Angular Rotation)|Original PID's]].
====Initialize the PID's====
:1. To start we create a struct with all the necessary variables (code from ''pid.h''):
<blockquote>
<code>
<pre>
typedef struct
{
float desired; //< set point
float error; //< error
float prevError; //< previous error
float integ; //< integral
float deriv; //< derivative
float kp; //< proportional gain
float ki; //< integral gain
float kd; //< derivative gain
float outP; //< proportional output (debugging)
float outI; //< integral output (debugging)
float outD; //< derivative output (debugging)
float iLimit; //< integral limit
float iLimitLow; //< integral limit
float dt; //< delta-time dt
float angularLimit; //sets limit for how far Crazyflie can tip, to prevent flipping
float angularLimitLow; //^
float thrustLimit; //Sets upper limit for Thrust Output (60000?) **?
float thrustLimitLow; //Sets lower limit for thrust Output (10001)
} PidObject;
</pre>
</code>
</blockquote>
:2. To simplify scaling up the code to multiple Crazyflies, we will create a <code> ControllerObject </code> that contains multiple PID structs as shown (code in ''controller.h''):
<blockquote>
<code>
<pre>
typedef struct
{
PidObject pidRoll;
PidObject pidPitch;
PidObject pidYaw;
PidObject pidX;
PidObject pidY;
PidObject pidZ;
bool isInit;
} ControllerObject;
</pre>
</code>
</blockquote>
:3. Then we initialize the Objects to 0 at the start of each run (code in ''eris_vrpn.cpp''):
<blockquote>
<code>
<pre>
ControllerObject pidCtrl1 = { 0 }; // init all fields to zero
ControllerObject pidCtrl2 = { 0 }; // init all fields to zero
ControllerObject pidCtrl3 = { 0 }; // init all fields to zero
ControllerObject pidCtrl4 = { 0 }; // init all fields to zero
</pre>
</code>
</blockquote>
:4. Then populate the PidObjects with the desired parameters (code in ''pid.c''):
<blockquote>
<code>
<pre>
void pidInit(PidObject* pid, const float desired, const float kp,
const float ki, const float kd, const float dt)
{
pid->error = 0;
pid->prevError = 0;
pid->integ = 0;
pid->deriv = 0;
pid->desired = desired;
pid->kp = kp;
pid->ki = ki;
pid->kd = kd;
pid->iLimit = DEFAULT_PID_INTEGRATION_LIMIT;
pid->iLimitLow = -DEFAULT_PID_INTEGRATION_LIMIT;
pid->angularLimit = DEFAULT_PID_ANGLE_OUTPUT;
pid->angularLimitLow = -DEFAULT_PID_ANGLE_OUTPUT;
pid->thrustLimit = DEFAULT_PID_HIGH_THRUST_LIMIT;
pid->thrustLimitLow = DEFAULT_PID_LOW_THRUST_LIMIT;
pid->dt = dt;
}
</pre>
</code>
</blockquote>
Using the above function for each of the <code>PidObjects</code> inside of the <code>ControllerObject</code> below (code in ''controller.c''):
<blockquote>
<code>
<pre>
void controllerInit( ControllerObject * ctrl )
{
if(ctrl->isInit)
return;
pidInit(&ctrl->pidY, 0, PID_Y_KP, PID_Y_KI, PID_Y_KD, CAMERA_UPDATE_DT); //for Roll PID
pidInit(&ctrl->pidX, 0, PID_X_KP, PID_X_KI, PID_X_KD, CAMERA_UPDATE_DT); //for Pitch PID
pidInit(&ctrl->pidYaw, 0, PID_YAW_KP, PID_YAW_KI, PID_YAW_KD, CAMERA_UPDATE_DT);
pidInit(&ctrl->pidZ, 0, PID_Z_KP, PID_Z_KI, PID_Z_KD, CAMERA_UPDATE_DT);
pidSetIntegralLimit(&ctrl->pidY, PID_Y_INTEGRATION_LIMIT);
pidSetIntegralLimit(&ctrl->pidX, PID_X_INTEGRATION_LIMIT);
pidSetIntegralLimit(&ctrl->pidYaw, PID_YAW_INTEGRATION_LIMIT);
pidSetIntegralLimit(&ctrl->pidZ, PID_Z_INTEGRATION_LIMIT);
ctrl->isInit = true;
}
</pre>
</code>
</blockquote>
'''Note:''' If we have multiple Crazyflies we need a <code>ControllerObject</code> for each Crazyflie (code in ''eris_vrpn.cpp'')
<blockquote>
<code>
<pre>
controllerResetAllPID( &pidCtrl1 );
controllerInit( &pidCtrl1 );
#endif
#if NUM_QUADS >= 2
controllerResetAllPID( &pidCtrl2 );
controllerInit( &pidCtrl2 );
#endif
#if NUM_QUADS >=3
controllerResetAllPID( &pidCtrl3 );
controllerInit( &pidCtrl3 );
#endif
#if NUM_QUADS >=4
controllerResetAllPID( &pidCtrl4 );
controllerInit( &pidCtrl4 );
#endif
</pre>
</code>
</blockquote>
Now the initialization of the Controllers is complete.
====Calculating the PID's====
:1. Each loop we want to calculate the PID output (code in ''pid.c''):
<blockquote>
<code>
<pre>
float pidUpdateAngle(PidObject* pid, const float measured, const bool updateError) //**USED FOR ATTITUDE CONTROL
{
float output;
if(updateError)
{
pid->error = pid->desired - measured; //Calculates current error
}
pid->integ += pid->error * pid->dt; //Calculates integral term
if(pid->integ > pid->iLimit) //Checks that the integral term stays below the integral limit (anti-windup)
{
pid->integ = pid->iLimit;
}
else if(pid->integ < pid->iLimitLow)
{
pid->integ = pid->iLimitLow;
}
pid->deriv = (pid->error - pid->prevError) / pid->dt; //Calculates derivative term
pid->outP = pid->kp* pid->error;
pid->outI = pid->ki * pid->integ;
pid->outD = pid->kd * pid->deriv;
output = pid->outP + pid->outI + pid->outD; //Adds up all 3 calculated terms for output
if(output > pid->angularLimit) //Limits amount Crazyflie can tip
{
output = pid->angularLimit;
}
if(output < pid->angularLimitLow) //Limits amount Crazyflie can tip
{
output = pid->angularLimitLow;
}
pid->prevError = pid->error; //Stores the current error for next loop
return output;
}
</pre>
</code>
</blockquote>
'''Note:''' There are 3 different versions of this Function (for Angle, Thrust, and Yaw) since each has different output limits.
:2. Using the function above, combine all PID calculations into one function (code in ''controller.c''):
<blockquote>
<code>
<pre>
void controllerCorrectAttitudePID(ControllerObject * ctrl,
float xPositionActual, float yPositionActual, float zPositionActual, float eulerYawActual, float xPositionDesired, float yPositionDesired,
float zPositionDesired, float eulerYawDesired, float* rollControlOutput, float* pitchControlOutput, float* yawControlOutput, float* thrustControlOutput)
{
pidSetDesired(&ctrl->pidX, xPositionDesired);
*pitchControlOutput = pidUpdateAngle(&ctrl->pidX, xPositionActual, false); //Originally true
pidSetDesired(&ctrl->pidY, yPositionDesired);
*rollControlOutput = pidUpdateAngle(&ctrl->pidY, yPositionActual, false); //Originally true
pidSetDesired(&ctrl->pidZ, zPositionDesired);
*thrustControlOutput = pidUpdateThrust(&ctrl->pidZ,zPositionActual, true);
float yawError;
pidSetDesired(&ctrl->pidYaw, eulerYawDesired);
yawError = eulerYawDesired - eulerYawActual;
if(yawError > 180.0) //Ensures Yaw error stays between -180 and 180 degrees
yawError -= 360.0;
else if(yawError < -180.0)
yawError += 360.0;
pidSetError(&ctrl->pidYaw, yawError);
*yawControlOutput = pidUpdateYaw(&ctrl->pidYaw, eulerYawActual, true); //originally false
}
</pre>
</code>
</blockquote>
:3. In each Callback, calculate the Controller outputs, assigned to pointer values<code>*rollControlOutput</code>, <code>*pitchControlOutput</code>, etc... (code in ''eris_vrpn.cpp''):
<blockquote>
<code>
<pre>
xError1 = xPositionDesired1 - xPosition1;
yError1 = yPositionDesired1 - yPosition1; //Calculates error externally
controllerSetXYError(&pidCtrl1, xError1, yError1);
controllerCorrectAttitudePID(&pidCtrl1, t.pos[0], t.pos[1], zPosition1, correctedYaw1,
xPositionDesired1, yPositionDesired1, zPositionDesired1,
yawDesired1, &rollControlOutput1, &pitchControlOutput1,
&yawControlOutput1, &thrustControlOutput1);
</pre>
</code>
</blockquote>
'''Note:''' We calculate error externally for X and Y because certain swarm controllers need special setpoint modifiers (this way we can switch modes without effecting the default setpoint):
'''Example:''' Follow Hand Mode Error (Crazyflie1 will have setpoint -0.5 m lower in X and +0.5 m higher in Y than your hand trackable):
<blockquote>
<code>
<pre>
...
xError1 = (xPositionHand - 0.5) - xPosition1;
yError1 = (yPositionHand + 0.5) - yPosition1;
controllerSetXYError(&pidCtrl1, xError1, yError1);
...
</pre>
</code>
</blockquote>
:4. Repeat for each set of new location data.
----
<center> '''Modifications Directory''' </center>
<center> [[Crazyflie Swarm|Crazyflie Swarm Home]] | [[Controller]] | [[Logging]] | [[Keyboard Commands]] | [[USB Radio#Changing Radio Channel|Changing Radio Channel]] | [[Flight Modes]] | [[Callbacks]] | [[Adding a Crazyflie]] | [[Firmware]] </center>
e95ff224b5a54fa5b3eb4dce7699fa1761974710
69
68
2016-07-13T18:07:39Z
Jnoronha
3
spaced the directory footer better
wikitext
text/x-wiki
The Crazyflie platform is completely customizable when it comes to the control design. As long as the controller can be written in C or C++, we can implement it in the Platform. This applies to both the controllers run on the PC Client and the controllers run on the Firmware of the Crazyflie. Originally the only controllers in the Platform were Firmware PID's that controlled the angular position and rates of the Crazyflie for hand flight. The original controller layout can be seen here [[#Original PID Controllers (Angular Rotation)|Original PID's]].
Below you will find documentation on the different types of Controllers that have been applied to the platform, organized by their location in the Platform.
== Firmware ==
=== Original PID Controllers (Angular Rotation) ===
Directly on the Crazyflie Firmware there are 5 PID controllers as seen here:
[[Image:FirmwareOnlyPIDArchitecture.png|500px]]
The Pitch and Roll angular position PID's receive constant setpoints from some outside source (gamepad controller or automated controller). The outputs of those angular position controllers is then fed into the angular rate controllers as shown. This final output is then fed into the Motor Command block which converts the angular rate setpoints into motor commands.
----
===State Estimator===
('''***NOT YET IMPLEMENTED***''')
Bitcraze is currently working on adding a state estimator onto the Firmware to handle control calculations instead of the PID.
The code is in place but the controller is not yet used as of '''7/13/16'''.
== PC Client ==
=== PID Controllers (Position and Yaw) ===
The first controller implemented on the Client were 4 PID controllers used to stabilize the Crazyflie's position in X, Y, and Z, and angular position in Yaw respectively. These PID's feed directly into the Firmware PID's as seen here:
[[Image:CompletePIDArchitectureFigure.png|500px]]
The controllers inside the red box are the original PID controllers located on the Firmware as shown above in the [[#Original PID Controllers (Angular Rotation)|Original PID's]].
====Initialize the PID's====
:1. To start we create a struct with all the necessary variables (code from ''pid.h''):
<blockquote>
<code>
<pre>
typedef struct
{
float desired; //< set point
float error; //< error
float prevError; //< previous error
float integ; //< integral
float deriv; //< derivative
float kp; //< proportional gain
float ki; //< integral gain
float kd; //< derivative gain
float outP; //< proportional output (debugging)
float outI; //< integral output (debugging)
float outD; //< derivative output (debugging)
float iLimit; //< integral limit
float iLimitLow; //< integral limit
float dt; //< delta-time dt
float angularLimit; //sets limit for how far Crazyflie can tip, to prevent flipping
float angularLimitLow; //^
float thrustLimit; //Sets upper limit for Thrust Output (60000?) **?
float thrustLimitLow; //Sets lower limit for thrust Output (10001)
} PidObject;
</pre>
</code>
</blockquote>
:2. To simplify scaling up the code to multiple Crazyflies, we will create a <code> ControllerObject </code> that contains multiple PID structs as shown (code in ''controller.h''):
<blockquote>
<code>
<pre>
typedef struct
{
PidObject pidRoll;
PidObject pidPitch;
PidObject pidYaw;
PidObject pidX;
PidObject pidY;
PidObject pidZ;
bool isInit;
} ControllerObject;
</pre>
</code>
</blockquote>
:3. Then we initialize the Objects to 0 at the start of each run (code in ''eris_vrpn.cpp''):
<blockquote>
<code>
<pre>
ControllerObject pidCtrl1 = { 0 }; // init all fields to zero
ControllerObject pidCtrl2 = { 0 }; // init all fields to zero
ControllerObject pidCtrl3 = { 0 }; // init all fields to zero
ControllerObject pidCtrl4 = { 0 }; // init all fields to zero
</pre>
</code>
</blockquote>
:4. Then populate the PidObjects with the desired parameters (code in ''pid.c''):
<blockquote>
<code>
<pre>
void pidInit(PidObject* pid, const float desired, const float kp,
const float ki, const float kd, const float dt)
{
pid->error = 0;
pid->prevError = 0;
pid->integ = 0;
pid->deriv = 0;
pid->desired = desired;
pid->kp = kp;
pid->ki = ki;
pid->kd = kd;
pid->iLimit = DEFAULT_PID_INTEGRATION_LIMIT;
pid->iLimitLow = -DEFAULT_PID_INTEGRATION_LIMIT;
pid->angularLimit = DEFAULT_PID_ANGLE_OUTPUT;
pid->angularLimitLow = -DEFAULT_PID_ANGLE_OUTPUT;
pid->thrustLimit = DEFAULT_PID_HIGH_THRUST_LIMIT;
pid->thrustLimitLow = DEFAULT_PID_LOW_THRUST_LIMIT;
pid->dt = dt;
}
</pre>
</code>
</blockquote>
Using the above function for each of the <code>PidObjects</code> inside of the <code>ControllerObject</code> below (code in ''controller.c''):
<blockquote>
<code>
<pre>
void controllerInit( ControllerObject * ctrl )
{
if(ctrl->isInit)
return;
pidInit(&ctrl->pidY, 0, PID_Y_KP, PID_Y_KI, PID_Y_KD, CAMERA_UPDATE_DT); //for Roll PID
pidInit(&ctrl->pidX, 0, PID_X_KP, PID_X_KI, PID_X_KD, CAMERA_UPDATE_DT); //for Pitch PID
pidInit(&ctrl->pidYaw, 0, PID_YAW_KP, PID_YAW_KI, PID_YAW_KD, CAMERA_UPDATE_DT);
pidInit(&ctrl->pidZ, 0, PID_Z_KP, PID_Z_KI, PID_Z_KD, CAMERA_UPDATE_DT);
pidSetIntegralLimit(&ctrl->pidY, PID_Y_INTEGRATION_LIMIT);
pidSetIntegralLimit(&ctrl->pidX, PID_X_INTEGRATION_LIMIT);
pidSetIntegralLimit(&ctrl->pidYaw, PID_YAW_INTEGRATION_LIMIT);
pidSetIntegralLimit(&ctrl->pidZ, PID_Z_INTEGRATION_LIMIT);
ctrl->isInit = true;
}
</pre>
</code>
</blockquote>
'''Note:''' If we have multiple Crazyflies we need a <code>ControllerObject</code> for each Crazyflie (code in ''eris_vrpn.cpp'')
<blockquote>
<code>
<pre>
controllerResetAllPID( &pidCtrl1 );
controllerInit( &pidCtrl1 );
#endif
#if NUM_QUADS >= 2
controllerResetAllPID( &pidCtrl2 );
controllerInit( &pidCtrl2 );
#endif
#if NUM_QUADS >=3
controllerResetAllPID( &pidCtrl3 );
controllerInit( &pidCtrl3 );
#endif
#if NUM_QUADS >=4
controllerResetAllPID( &pidCtrl4 );
controllerInit( &pidCtrl4 );
#endif
</pre>
</code>
</blockquote>
Now the initialization of the Controllers is complete.
====Calculating the PID's====
:1. Each loop we want to calculate the PID output (code in ''pid.c''):
<blockquote>
<code>
<pre>
float pidUpdateAngle(PidObject* pid, const float measured, const bool updateError) //**USED FOR ATTITUDE CONTROL
{
float output;
if(updateError)
{
pid->error = pid->desired - measured; //Calculates current error
}
pid->integ += pid->error * pid->dt; //Calculates integral term
if(pid->integ > pid->iLimit) //Checks that the integral term stays below the integral limit (anti-windup)
{
pid->integ = pid->iLimit;
}
else if(pid->integ < pid->iLimitLow)
{
pid->integ = pid->iLimitLow;
}
pid->deriv = (pid->error - pid->prevError) / pid->dt; //Calculates derivative term
pid->outP = pid->kp* pid->error;
pid->outI = pid->ki * pid->integ;
pid->outD = pid->kd * pid->deriv;
output = pid->outP + pid->outI + pid->outD; //Adds up all 3 calculated terms for output
if(output > pid->angularLimit) //Limits amount Crazyflie can tip
{
output = pid->angularLimit;
}
if(output < pid->angularLimitLow) //Limits amount Crazyflie can tip
{
output = pid->angularLimitLow;
}
pid->prevError = pid->error; //Stores the current error for next loop
return output;
}
</pre>
</code>
</blockquote>
'''Note:''' There are 3 different versions of this Function (for Angle, Thrust, and Yaw) since each has different output limits.
:2. Using the function above, combine all PID calculations into one function (code in ''controller.c''):
<blockquote>
<code>
<pre>
void controllerCorrectAttitudePID(ControllerObject * ctrl,
float xPositionActual, float yPositionActual, float zPositionActual, float eulerYawActual, float xPositionDesired, float yPositionDesired,
float zPositionDesired, float eulerYawDesired, float* rollControlOutput, float* pitchControlOutput, float* yawControlOutput, float* thrustControlOutput)
{
pidSetDesired(&ctrl->pidX, xPositionDesired);
*pitchControlOutput = pidUpdateAngle(&ctrl->pidX, xPositionActual, false); //Originally true
pidSetDesired(&ctrl->pidY, yPositionDesired);
*rollControlOutput = pidUpdateAngle(&ctrl->pidY, yPositionActual, false); //Originally true
pidSetDesired(&ctrl->pidZ, zPositionDesired);
*thrustControlOutput = pidUpdateThrust(&ctrl->pidZ,zPositionActual, true);
float yawError;
pidSetDesired(&ctrl->pidYaw, eulerYawDesired);
yawError = eulerYawDesired - eulerYawActual;
if(yawError > 180.0) //Ensures Yaw error stays between -180 and 180 degrees
yawError -= 360.0;
else if(yawError < -180.0)
yawError += 360.0;
pidSetError(&ctrl->pidYaw, yawError);
*yawControlOutput = pidUpdateYaw(&ctrl->pidYaw, eulerYawActual, true); //originally false
}
</pre>
</code>
</blockquote>
:3. In each Callback, calculate the Controller outputs, assigned to pointer values<code>*rollControlOutput</code>, <code>*pitchControlOutput</code>, etc... (code in ''eris_vrpn.cpp''):
<blockquote>
<code>
<pre>
xError1 = xPositionDesired1 - xPosition1;
yError1 = yPositionDesired1 - yPosition1; //Calculates error externally
controllerSetXYError(&pidCtrl1, xError1, yError1);
controllerCorrectAttitudePID(&pidCtrl1, t.pos[0], t.pos[1], zPosition1, correctedYaw1,
xPositionDesired1, yPositionDesired1, zPositionDesired1,
yawDesired1, &rollControlOutput1, &pitchControlOutput1,
&yawControlOutput1, &thrustControlOutput1);
</pre>
</code>
</blockquote>
'''Note:''' We calculate error externally for X and Y because certain swarm controllers need special setpoint modifiers (this way we can switch modes without effecting the default setpoint):
'''Example:''' Follow Hand Mode Error (Crazyflie1 will have setpoint -0.5 m lower in X and +0.5 m higher in Y than your hand trackable):
<blockquote>
<code>
<pre>
...
xError1 = (xPositionHand - 0.5) - xPosition1;
yError1 = (yPositionHand + 0.5) - yPosition1;
controllerSetXYError(&pidCtrl1, xError1, yError1);
...
</pre>
</code>
</blockquote>
:4. Repeat for each set of new location data.
----
<center> '''Modifications Directory''' </center>
<center> [[Crazyflie Swarm|Crazyflie Swarm Home]] | [[Controller]] | [[Logging]] | [[Keyboard Commands]] | [[USB Radio#Changing Radio Channel|Changing Radio Channel]] | [[Flight Modes]] | [[Callbacks]] | [[Adding a Crazyflie]] | [[Firmware]] </center>
def5be89202f4e14a8c2ad3a915800c802309765
71
69
2016-07-13T18:11:21Z
Jnoronha
3
added ellipses
wikitext
text/x-wiki
The Crazyflie platform is completely customizable when it comes to the control design. As long as the controller can be written in C or C++, we can implement it in the Platform. This applies to both the controllers run on the PC Client and the controllers run on the Firmware of the Crazyflie. Originally the only controllers in the Platform were Firmware PID's that controlled the angular position and rates of the Crazyflie for hand flight. The original controller layout can be seen here [[#Original PID Controllers (Angular Rotation)|Original PID's]].
Below you will find documentation on the different types of Controllers that have been applied to the platform, organized by their location in the Platform.
== Firmware ==
=== Original PID Controllers (Angular Rotation) ===
Directly on the Crazyflie Firmware there are 5 PID controllers as seen here:
[[Image:FirmwareOnlyPIDArchitecture.png|500px]]
The Pitch and Roll angular position PID's receive constant setpoints from some outside source (gamepad controller or automated controller). The outputs of those angular position controllers is then fed into the angular rate controllers as shown. This final output is then fed into the Motor Command block which converts the angular rate setpoints into motor commands.
----
===State Estimator===
('''***NOT YET IMPLEMENTED***''')
Bitcraze is currently working on adding a state estimator onto the Firmware to handle control calculations instead of the PID.
The code is in place but the controller is not yet used as of '''7/13/16'''.
== PC Client ==
=== PID Controllers (Position and Yaw) ===
The first controller implemented on the Client were 4 PID controllers used to stabilize the Crazyflie's position in X, Y, and Z, and angular position in Yaw respectively. These PID's feed directly into the Firmware PID's as seen here:
[[Image:CompletePIDArchitectureFigure.png|500px]]
The controllers inside the red box are the original PID controllers located on the Firmware as shown above in the [[#Original PID Controllers (Angular Rotation)|Original PID's]].
====Initialize the PID's====
:1. To start we create a struct with all the necessary variables (code from ''pid.h''):
<blockquote>
<code>
<pre>
typedef struct
{
float desired; //< set point
float error; //< error
float prevError; //< previous error
float integ; //< integral
float deriv; //< derivative
float kp; //< proportional gain
float ki; //< integral gain
float kd; //< derivative gain
float outP; //< proportional output (debugging)
float outI; //< integral output (debugging)
float outD; //< derivative output (debugging)
float iLimit; //< integral limit
float iLimitLow; //< integral limit
float dt; //< delta-time dt
float angularLimit; //sets limit for how far Crazyflie can tip, to prevent flipping
float angularLimitLow; //^
float thrustLimit; //Sets upper limit for Thrust Output (60000?) **?
float thrustLimitLow; //Sets lower limit for thrust Output (10001)
} PidObject;
</pre>
</code>
</blockquote>
:2. To simplify scaling up the code to multiple Crazyflies, we will create a <code> ControllerObject </code> that contains multiple PID structs as shown (code in ''controller.h''):
<blockquote>
<code>
<pre>
typedef struct
{
PidObject pidRoll;
PidObject pidPitch;
PidObject pidYaw;
PidObject pidX;
PidObject pidY;
PidObject pidZ;
bool isInit;
} ControllerObject;
</pre>
</code>
</blockquote>
:3. Then we initialize the Objects to 0 at the start of each run (code in ''eris_vrpn.cpp''):
<blockquote>
<code>
<pre>
ControllerObject pidCtrl1 = { 0 }; // init all fields to zero
ControllerObject pidCtrl2 = { 0 }; // init all fields to zero
ControllerObject pidCtrl3 = { 0 }; // init all fields to zero
ControllerObject pidCtrl4 = { 0 }; // init all fields to zero
</pre>
</code>
</blockquote>
:4. Then populate the PidObjects with the desired parameters (code in ''pid.c''):
<blockquote>
<code>
<pre>
void pidInit(PidObject* pid, const float desired, const float kp,
const float ki, const float kd, const float dt)
{
pid->error = 0;
pid->prevError = 0;
pid->integ = 0;
pid->deriv = 0;
pid->desired = desired;
pid->kp = kp;
pid->ki = ki;
pid->kd = kd;
pid->iLimit = DEFAULT_PID_INTEGRATION_LIMIT;
pid->iLimitLow = -DEFAULT_PID_INTEGRATION_LIMIT;
pid->angularLimit = DEFAULT_PID_ANGLE_OUTPUT;
pid->angularLimitLow = -DEFAULT_PID_ANGLE_OUTPUT;
pid->thrustLimit = DEFAULT_PID_HIGH_THRUST_LIMIT;
pid->thrustLimitLow = DEFAULT_PID_LOW_THRUST_LIMIT;
pid->dt = dt;
}
</pre>
</code>
</blockquote>
Using the above function for each of the <code>PidObjects</code> inside of the <code>ControllerObject</code> below (code in ''controller.c''):
<blockquote>
<code>
<pre>
void controllerInit( ControllerObject * ctrl )
{
if(ctrl->isInit)
return;
pidInit(&ctrl->pidY, 0, PID_Y_KP, PID_Y_KI, PID_Y_KD, CAMERA_UPDATE_DT); //for Roll PID
pidInit(&ctrl->pidX, 0, PID_X_KP, PID_X_KI, PID_X_KD, CAMERA_UPDATE_DT); //for Pitch PID
pidInit(&ctrl->pidYaw, 0, PID_YAW_KP, PID_YAW_KI, PID_YAW_KD, CAMERA_UPDATE_DT);
pidInit(&ctrl->pidZ, 0, PID_Z_KP, PID_Z_KI, PID_Z_KD, CAMERA_UPDATE_DT);
pidSetIntegralLimit(&ctrl->pidY, PID_Y_INTEGRATION_LIMIT);
pidSetIntegralLimit(&ctrl->pidX, PID_X_INTEGRATION_LIMIT);
pidSetIntegralLimit(&ctrl->pidYaw, PID_YAW_INTEGRATION_LIMIT);
pidSetIntegralLimit(&ctrl->pidZ, PID_Z_INTEGRATION_LIMIT);
ctrl->isInit = true;
}
</pre>
</code>
</blockquote>
'''Note:''' If we have multiple Crazyflies we need a <code>ControllerObject</code> for each Crazyflie (code in ''eris_vrpn.cpp'')
<blockquote>
<code>
<pre>
controllerResetAllPID( &pidCtrl1 );
controllerInit( &pidCtrl1 );
#endif
#if NUM_QUADS >= 2
controllerResetAllPID( &pidCtrl2 );
controllerInit( &pidCtrl2 );
#endif
#if NUM_QUADS >=3
controllerResetAllPID( &pidCtrl3 );
controllerInit( &pidCtrl3 );
#endif
#if NUM_QUADS >=4
controllerResetAllPID( &pidCtrl4 );
controllerInit( &pidCtrl4 );
#endif
</pre>
</code>
</blockquote>
Now the initialization of the Controllers is complete.
====Calculating the PID's====
:1. Each loop we want to calculate the PID output (code in ''pid.c''):
<blockquote>
<code>
<pre>
float pidUpdateAngle(PidObject* pid, const float measured, const bool updateError) //**USED FOR ATTITUDE CONTROL
{
float output;
if(updateError)
{
pid->error = pid->desired - measured; //Calculates current error
}
pid->integ += pid->error * pid->dt; //Calculates integral term
if(pid->integ > pid->iLimit) //Checks that the integral term stays below the integral limit (anti-windup)
{
pid->integ = pid->iLimit;
}
else if(pid->integ < pid->iLimitLow)
{
pid->integ = pid->iLimitLow;
}
pid->deriv = (pid->error - pid->prevError) / pid->dt; //Calculates derivative term
pid->outP = pid->kp* pid->error;
pid->outI = pid->ki * pid->integ;
pid->outD = pid->kd * pid->deriv;
output = pid->outP + pid->outI + pid->outD; //Adds up all 3 calculated terms for output
if(output > pid->angularLimit) //Limits amount Crazyflie can tip
{
output = pid->angularLimit;
}
if(output < pid->angularLimitLow) //Limits amount Crazyflie can tip
{
output = pid->angularLimitLow;
}
pid->prevError = pid->error; //Stores the current error for next loop
return output;
}
</pre>
</code>
</blockquote>
'''Note:''' There are 3 different versions of this Function (for Angle, Thrust, and Yaw) since each has different output limits.
:2. Using the function above, combine all PID calculations into one function (code in ''controller.c''):
<blockquote>
<code>
<pre>
void controllerCorrectAttitudePID(ControllerObject * ctrl,
float xPositionActual, float yPositionActual, float zPositionActual, float eulerYawActual, float xPositionDesired, float yPositionDesired,
float zPositionDesired, float eulerYawDesired, float* rollControlOutput, float* pitchControlOutput, float* yawControlOutput, float* thrustControlOutput)
{
pidSetDesired(&ctrl->pidX, xPositionDesired);
*pitchControlOutput = pidUpdateAngle(&ctrl->pidX, xPositionActual, false); //Originally true
pidSetDesired(&ctrl->pidY, yPositionDesired);
*rollControlOutput = pidUpdateAngle(&ctrl->pidY, yPositionActual, false); //Originally true
pidSetDesired(&ctrl->pidZ, zPositionDesired);
*thrustControlOutput = pidUpdateThrust(&ctrl->pidZ,zPositionActual, true);
float yawError;
pidSetDesired(&ctrl->pidYaw, eulerYawDesired);
yawError = eulerYawDesired - eulerYawActual;
if(yawError > 180.0) //Ensures Yaw error stays between -180 and 180 degrees
yawError -= 360.0;
else if(yawError < -180.0)
yawError += 360.0;
pidSetError(&ctrl->pidYaw, yawError);
*yawControlOutput = pidUpdateYaw(&ctrl->pidYaw, eulerYawActual, true); //originally false
}
</pre>
</code>
</blockquote>
:3. In each Callback, calculate the Controller outputs, assigned to pointer values<code>*rollControlOutput</code>, <code>*pitchControlOutput</code>, etc... (code in ''eris_vrpn.cpp''):
<blockquote>
<code>
<pre>
xError1 = xPositionDesired1 - xPosition1;
yError1 = yPositionDesired1 - yPosition1; //Calculates error externally
controllerSetXYError(&pidCtrl1, xError1, yError1);
controllerCorrectAttitudePID(&pidCtrl1, t.pos[0], t.pos[1], zPosition1, correctedYaw1,
xPositionDesired1, yPositionDesired1, zPositionDesired1,
yawDesired1, &rollControlOutput1, &pitchControlOutput1,
&yawControlOutput1, &thrustControlOutput1);
</pre>
</code>
</blockquote>
'''Note:''' We calculate error externally for X and Y because certain swarm controllers need special setpoint modifiers (this way we can switch modes without effecting the default setpoint):
'''Example:''' Follow Hand Mode Error (Crazyflie1 will have setpoint -0.5 m lower in X and +0.5 m higher in Y than your hand trackable):
<blockquote>
<code>
<pre>
...
xError1 = (xPositionHand - 0.5) - xPosition1;
yError1 = (yPositionHand + 0.5) - yPosition1;
controllerSetXYError(&pidCtrl1, xError1, yError1);
...
</pre>
</code>
</blockquote>
:4. Repeat for each set of new location data...
----
<center> '''Modifications Directory''' </center>
<center> [[Crazyflie Swarm|Crazyflie Swarm Home]] | [[Controller]] | [[Logging]] | [[Keyboard Commands]] | [[USB Radio#Changing Radio Channel|Changing Radio Channel]] | [[Flight Modes]] | [[Callbacks]] | [[Adding a Crazyflie]] | [[Firmware]] </center>
8655e4c99f766f75f68dbe1d76872bbcc2cf8d77
72
71
2016-07-13T18:25:29Z
Jnoronha
3
Added disclaimer to state estimator heading
wikitext
text/x-wiki
The Crazyflie platform is completely customizable when it comes to the control design. As long as the controller can be written in C or C++, we can implement it in the Platform. This applies to both the controllers run on the PC Client and the controllers run on the Firmware of the Crazyflie. Originally the only controllers in the Platform were Firmware PID's that controlled the angular position and rates of the Crazyflie for hand flight. The original controller layout can be seen here [[#Original PID Controllers (Angular Rotation)|Original PID's]].
Below you will find documentation on the different types of Controllers that have been applied to the platform, organized by their location in the Platform.
== Firmware ==
=== Original PID Controllers (Angular Rotation) ===
Directly on the Crazyflie Firmware there are 5 PID controllers as seen here:
[[Image:FirmwareOnlyPIDArchitecture.png|500px]]
The Pitch and Roll angular position PID's receive constant setpoints from some outside source (gamepad controller or automated controller). The outputs of those angular position controllers is then fed into the angular rate controllers as shown. This final output is then fed into the Motor Command block which converts the angular rate setpoints into motor commands.
----
===State Estimator (Not Implemented Yet)===
('''***NOT YET IMPLEMENTED***''')
Bitcraze is currently working on adding a state estimator onto the Firmware to handle control calculations instead of the PID.
The code is in place but the controller is not yet used as of '''7/13/16'''.
== PC Client ==
=== PID Controllers (Position and Yaw) ===
The first controller implemented on the Client were 4 PID controllers used to stabilize the Crazyflie's position in X, Y, and Z, and angular position in Yaw respectively. These PID's feed directly into the Firmware PID's as seen here:
[[Image:CompletePIDArchitectureFigure.png|500px]]
The controllers inside the red box are the original PID controllers located on the Firmware as shown above in the [[#Original PID Controllers (Angular Rotation)|Original PID's]].
====Initialize the PID's====
:1. To start we create a struct with all the necessary variables (code from ''pid.h''):
<blockquote>
<code>
<pre>
typedef struct
{
float desired; //< set point
float error; //< error
float prevError; //< previous error
float integ; //< integral
float deriv; //< derivative
float kp; //< proportional gain
float ki; //< integral gain
float kd; //< derivative gain
float outP; //< proportional output (debugging)
float outI; //< integral output (debugging)
float outD; //< derivative output (debugging)
float iLimit; //< integral limit
float iLimitLow; //< integral limit
float dt; //< delta-time dt
float angularLimit; //sets limit for how far Crazyflie can tip, to prevent flipping
float angularLimitLow; //^
float thrustLimit; //Sets upper limit for Thrust Output (60000?) **?
float thrustLimitLow; //Sets lower limit for thrust Output (10001)
} PidObject;
</pre>
</code>
</blockquote>
:2. To simplify scaling up the code to multiple Crazyflies, we will create a <code> ControllerObject </code> that contains multiple PID structs as shown (code in ''controller.h''):
<blockquote>
<code>
<pre>
typedef struct
{
PidObject pidRoll;
PidObject pidPitch;
PidObject pidYaw;
PidObject pidX;
PidObject pidY;
PidObject pidZ;
bool isInit;
} ControllerObject;
</pre>
</code>
</blockquote>
:3. Then we initialize the Objects to 0 at the start of each run (code in ''eris_vrpn.cpp''):
<blockquote>
<code>
<pre>
ControllerObject pidCtrl1 = { 0 }; // init all fields to zero
ControllerObject pidCtrl2 = { 0 }; // init all fields to zero
ControllerObject pidCtrl3 = { 0 }; // init all fields to zero
ControllerObject pidCtrl4 = { 0 }; // init all fields to zero
</pre>
</code>
</blockquote>
:4. Then populate the PidObjects with the desired parameters (code in ''pid.c''):
<blockquote>
<code>
<pre>
void pidInit(PidObject* pid, const float desired, const float kp,
const float ki, const float kd, const float dt)
{
pid->error = 0;
pid->prevError = 0;
pid->integ = 0;
pid->deriv = 0;
pid->desired = desired;
pid->kp = kp;
pid->ki = ki;
pid->kd = kd;
pid->iLimit = DEFAULT_PID_INTEGRATION_LIMIT;
pid->iLimitLow = -DEFAULT_PID_INTEGRATION_LIMIT;
pid->angularLimit = DEFAULT_PID_ANGLE_OUTPUT;
pid->angularLimitLow = -DEFAULT_PID_ANGLE_OUTPUT;
pid->thrustLimit = DEFAULT_PID_HIGH_THRUST_LIMIT;
pid->thrustLimitLow = DEFAULT_PID_LOW_THRUST_LIMIT;
pid->dt = dt;
}
</pre>
</code>
</blockquote>
Using the above function for each of the <code>PidObjects</code> inside of the <code>ControllerObject</code> below (code in ''controller.c''):
<blockquote>
<code>
<pre>
void controllerInit( ControllerObject * ctrl )
{
if(ctrl->isInit)
return;
pidInit(&ctrl->pidY, 0, PID_Y_KP, PID_Y_KI, PID_Y_KD, CAMERA_UPDATE_DT); //for Roll PID
pidInit(&ctrl->pidX, 0, PID_X_KP, PID_X_KI, PID_X_KD, CAMERA_UPDATE_DT); //for Pitch PID
pidInit(&ctrl->pidYaw, 0, PID_YAW_KP, PID_YAW_KI, PID_YAW_KD, CAMERA_UPDATE_DT);
pidInit(&ctrl->pidZ, 0, PID_Z_KP, PID_Z_KI, PID_Z_KD, CAMERA_UPDATE_DT);
pidSetIntegralLimit(&ctrl->pidY, PID_Y_INTEGRATION_LIMIT);
pidSetIntegralLimit(&ctrl->pidX, PID_X_INTEGRATION_LIMIT);
pidSetIntegralLimit(&ctrl->pidYaw, PID_YAW_INTEGRATION_LIMIT);
pidSetIntegralLimit(&ctrl->pidZ, PID_Z_INTEGRATION_LIMIT);
ctrl->isInit = true;
}
</pre>
</code>
</blockquote>
'''Note:''' If we have multiple Crazyflies we need a <code>ControllerObject</code> for each Crazyflie (code in ''eris_vrpn.cpp'')
<blockquote>
<code>
<pre>
controllerResetAllPID( &pidCtrl1 );
controllerInit( &pidCtrl1 );
#endif
#if NUM_QUADS >= 2
controllerResetAllPID( &pidCtrl2 );
controllerInit( &pidCtrl2 );
#endif
#if NUM_QUADS >=3
controllerResetAllPID( &pidCtrl3 );
controllerInit( &pidCtrl3 );
#endif
#if NUM_QUADS >=4
controllerResetAllPID( &pidCtrl4 );
controllerInit( &pidCtrl4 );
#endif
</pre>
</code>
</blockquote>
Now the initialization of the Controllers is complete.
====Calculating the PID's====
:1. Each loop we want to calculate the PID output (code in ''pid.c''):
<blockquote>
<code>
<pre>
float pidUpdateAngle(PidObject* pid, const float measured, const bool updateError) //**USED FOR ATTITUDE CONTROL
{
float output;
if(updateError)
{
pid->error = pid->desired - measured; //Calculates current error
}
pid->integ += pid->error * pid->dt; //Calculates integral term
if(pid->integ > pid->iLimit) //Checks that the integral term stays below the integral limit (anti-windup)
{
pid->integ = pid->iLimit;
}
else if(pid->integ < pid->iLimitLow)
{
pid->integ = pid->iLimitLow;
}
pid->deriv = (pid->error - pid->prevError) / pid->dt; //Calculates derivative term
pid->outP = pid->kp* pid->error;
pid->outI = pid->ki * pid->integ;
pid->outD = pid->kd * pid->deriv;
output = pid->outP + pid->outI + pid->outD; //Adds up all 3 calculated terms for output
if(output > pid->angularLimit) //Limits amount Crazyflie can tip
{
output = pid->angularLimit;
}
if(output < pid->angularLimitLow) //Limits amount Crazyflie can tip
{
output = pid->angularLimitLow;
}
pid->prevError = pid->error; //Stores the current error for next loop
return output;
}
</pre>
</code>
</blockquote>
'''Note:''' There are 3 different versions of this Function (for Angle, Thrust, and Yaw) since each has different output limits.
:2. Using the function above, combine all PID calculations into one function (code in ''controller.c''):
<blockquote>
<code>
<pre>
void controllerCorrectAttitudePID(ControllerObject * ctrl,
float xPositionActual, float yPositionActual, float zPositionActual, float eulerYawActual, float xPositionDesired, float yPositionDesired,
float zPositionDesired, float eulerYawDesired, float* rollControlOutput, float* pitchControlOutput, float* yawControlOutput, float* thrustControlOutput)
{
pidSetDesired(&ctrl->pidX, xPositionDesired);
*pitchControlOutput = pidUpdateAngle(&ctrl->pidX, xPositionActual, false); //Originally true
pidSetDesired(&ctrl->pidY, yPositionDesired);
*rollControlOutput = pidUpdateAngle(&ctrl->pidY, yPositionActual, false); //Originally true
pidSetDesired(&ctrl->pidZ, zPositionDesired);
*thrustControlOutput = pidUpdateThrust(&ctrl->pidZ,zPositionActual, true);
float yawError;
pidSetDesired(&ctrl->pidYaw, eulerYawDesired);
yawError = eulerYawDesired - eulerYawActual;
if(yawError > 180.0) //Ensures Yaw error stays between -180 and 180 degrees
yawError -= 360.0;
else if(yawError < -180.0)
yawError += 360.0;
pidSetError(&ctrl->pidYaw, yawError);
*yawControlOutput = pidUpdateYaw(&ctrl->pidYaw, eulerYawActual, true); //originally false
}
</pre>
</code>
</blockquote>
:3. In each Callback, calculate the Controller outputs, assigned to pointer values<code>*rollControlOutput</code>, <code>*pitchControlOutput</code>, etc... (code in ''eris_vrpn.cpp''):
<blockquote>
<code>
<pre>
xError1 = xPositionDesired1 - xPosition1;
yError1 = yPositionDesired1 - yPosition1; //Calculates error externally
controllerSetXYError(&pidCtrl1, xError1, yError1);
controllerCorrectAttitudePID(&pidCtrl1, t.pos[0], t.pos[1], zPosition1, correctedYaw1,
xPositionDesired1, yPositionDesired1, zPositionDesired1,
yawDesired1, &rollControlOutput1, &pitchControlOutput1,
&yawControlOutput1, &thrustControlOutput1);
</pre>
</code>
</blockquote>
'''Note:''' We calculate error externally for X and Y because certain swarm controllers need special setpoint modifiers (this way we can switch modes without effecting the default setpoint):
'''Example:''' Follow Hand Mode Error (Crazyflie1 will have setpoint -0.5 m lower in X and +0.5 m higher in Y than your hand trackable):
<blockquote>
<code>
<pre>
...
xError1 = (xPositionHand - 0.5) - xPosition1;
yError1 = (yPositionHand + 0.5) - yPosition1;
controllerSetXYError(&pidCtrl1, xError1, yError1);
...
</pre>
</code>
</blockquote>
:4. Repeat for each set of new location data...
----
<center> '''Modifications Directory''' </center>
<center> [[Crazyflie Swarm|Crazyflie Swarm Home]] | [[Controller]] | [[Logging]] | [[Keyboard Commands]] | [[USB Radio#Changing Radio Channel|Changing Radio Channel]] | [[Flight Modes]] | [[Callbacks]] | [[Adding a Crazyflie]] | [[Firmware]] </center>
ce5017ac82c7e736b57aa24915c37e1fc2063831
Crazyflie Swarm
0
2
70
17
2016-07-13T18:08:43Z
Jnoronha
3
Linked to radio channel change sub-section
wikitext
text/x-wiki
The Crazyflie Swarm is a Networked Control platform designed for students to learn more about control and for researchers that wish to apply their research in practice. Platform development was started during the Summer of 2015 and continues to this day.
Here you will find descriptions on how the platform works, how you can use it, and how you can get involved in developing the platform further!
== Background ==
The Crazyflie Swarm platform is based off of the ''Crazyflie'' Nano-quadcopter produced and maintained by [https://www.bitcraze.io/ Bitcraze]. The ''Crazyflie'' is completely open-source so we are able to look at and modify any part of the code and customize it to our needs.
=== Major Platform Components: ===
[[Image: High_Level_Figure_(Single_Radio_Single_Crazyflie_NO_NUMBERS_CROPPED).jpg|thumb|right|A high level overview of the Crazyflie Platform]]
*[[PC Client Software]]
*[[Firmware]]
*[[USB Radio]]
== Modifying the Platform ==
*[[Controller]]
*[[Logging]]
*[[Keyboard Commands]]
*[[USB Radio#Changing Radio Channel|Changing Radio Channel]]
*[[Flight Modes]]
*[[Callbacks]]
*[[Adding a Crazyflie]]
*[[:Firmware]]
== Frequently Asked Questions ==
For help with common problems and troubleshooting please see the [[FAQ]].
== [https://wiki.bitcraze.io/ Bitcraze Wiki] ==
Bitcraze maintains their own wiki on the many Crazyflie systems. If you can't find what you are looking for here, chances are they will have something to help.
e4eebec1bd740c1cc1b89406fef0d142d67b8185
73
70
2016-07-13T18:27:33Z
Jnoronha
3
added reminder to finish PC Client section
wikitext
text/x-wiki
The Crazyflie Swarm is a Networked Control platform designed for students to learn more about control and for researchers that wish to apply their research in practice. Platform development was started during the Summer of 2015 and continues to this day.
Here you will find descriptions on how the platform works, how you can use it, and how you can get involved in developing the platform further!
== Background ==
The Crazyflie Swarm platform is based off of the ''Crazyflie'' Nano-quadcopter produced and maintained by [https://www.bitcraze.io/ Bitcraze]. The ''Crazyflie'' is completely open-source so we are able to look at and modify any part of the code and customize it to our needs.
=== Major Platform Components: ===
[[Image: High_Level_Figure_(Single_Radio_Single_Crazyflie_NO_NUMBERS_CROPPED).jpg|thumb|right|A high level overview of the Crazyflie Platform]]
*[[PC Client Software]] '''(***TODO***)'''
*[[Firmware]]
*[[USB Radio]]
== Modifying the Platform ==
*[[Controller]]
*[[Logging]]
*[[Keyboard Commands]]
*[[USB Radio#Changing Radio Channel|Changing Radio Channel]]
*[[Flight Modes]]
*[[Callbacks]]
*[[Adding a Crazyflie]]
*[[:Firmware]]
== Frequently Asked Questions ==
For help with common problems and troubleshooting please see the [[FAQ]].
== [https://wiki.bitcraze.io/ Bitcraze Wiki] ==
Bitcraze maintains their own wiki on the many Crazyflie systems. If you can't find what you are looking for here, chances are they will have something to help.
dc1e9fabec8902b9f8cc8c67fcc29ec92f5b13f7
97
73
2016-07-19T18:56:18Z
Jnoronha
3
Removed TODO from client
wikitext
text/x-wiki
The Crazyflie Swarm is a Networked Control platform designed for students to learn more about control and for researchers that wish to apply their research in practice. Platform development was started during the Summer of 2015 and continues to this day.
Here you will find descriptions on how the platform works, how you can use it, and how you can get involved in developing the platform further!
== Background ==
The Crazyflie Swarm platform is based off of the ''Crazyflie'' Nano-quadcopter produced and maintained by [https://www.bitcraze.io/ Bitcraze]. The ''Crazyflie'' is completely open-source so we are able to look at and modify any part of the code and customize it to our needs.
=== Major Platform Components: ===
[[Image: High_Level_Figure_(Single_Radio_Single_Crazyflie_NO_NUMBERS_CROPPED).jpg|thumb|right|A high level overview of the Crazyflie Platform]]
*[[PC Client Software]]
*[[Firmware]]
*[[USB Radio]]
== Modifying the Platform ==
*[[Controller]]
*[[Logging]]
*[[Keyboard Commands]]
*[[USB Radio#Changing Radio Channel|Changing Radio Channel]]
*[[Flight Modes]]
*[[Callbacks]]
*[[Adding a Crazyflie]]
*[[:Firmware]]
== Frequently Asked Questions ==
For help with common problems and troubleshooting please see the [[FAQ]].
== [https://wiki.bitcraze.io/ Bitcraze Wiki] ==
Bitcraze maintains their own wiki on the many Crazyflie systems. If you can't find what you are looking for here, chances are they will have something to help.
e4eebec1bd740c1cc1b89406fef0d142d67b8185
File:DefaultCrazyflieGUIBootloader.JPG
6
23
74
47
2016-07-18T19:57:28Z
Jnoronha
3
uploaded a new version of "[[Image:DefaultCrazyflieGUIBootloader.JPG]]"
wikitext
text/x-wiki
Screenshot of the Crazyflie Bootloader User Interface.
9414da3f61ffe8574ac5f9b79654f2f8294c89b3
File:DefaultCrazyflieGUIConnectScreen.JPG
6
27
75
2016-07-18T19:58:42Z
Jnoronha
3
Screenshot of the Crazyflie GUI connect to radio window.
wikitext
text/x-wiki
Screenshot of the Crazyflie GUI connect to radio window.
4c03f28f200c96bb4f336f5e667304c98f3b4037
File:DefaultCrazyflieGUILoggerScreen.JPG
6
28
76
2016-07-18T20:00:03Z
Jnoronha
3
Screenshot of the Crazyflie GUI logging output
wikitext
text/x-wiki
Screenshot of the Crazyflie GUI logging output
8fb3c169c5958e65b424b65fa95db06f05872b2e
File:DefaultCrazyflieGUIParametersScreen.JPG
6
29
77
2016-07-18T20:00:55Z
Jnoronha
3
Screenshot of the Crazyflie GUI Parameters Tab
wikitext
text/x-wiki
Screenshot of the Crazyflie GUI Parameters Tab
ef7255336a61589fd230dbc1017eae357b6ae0be
File:CrazyflieLocationLayout.JPG
6
30
78
2016-07-18T20:02:10Z
Jnoronha
3
Photo of the Default locations of the Current 4 Crazyflies is laid out.
wikitext
text/x-wiki
Photo of the Default locations of the Current 4 Crazyflies is laid out.
d83b1de3cf06308f7fc268bde4ce5e929f30d497
File:CrazyflieTerminalInitial.png
6
31
86
2016-07-19T17:42:18Z
Jnoronha
3
Crazyflie Terminal showing the make command
wikitext
text/x-wiki
Crazyflie Terminal showing the make command
c6f990d31f07dfcf8d93d9f828ea053eeb121328
File:CrazyflieTerminalPostMake.png
6
32
87
2016-07-19T17:42:39Z
Jnoronha
3
Crazyflie Terminal showing an error free make build
wikitext
text/x-wiki
Crazyflie Terminal showing an error free make build
d6cea0bf6c7a21708537aa1d95eead63570705c8
File:3CrazyflieTerminalRunProgram.png
6
33
88
2016-07-19T17:42:57Z
Jnoronha
3
Crazyflie Terminal showing the run .exe command
wikitext
text/x-wiki
Crazyflie Terminal showing the run .exe command
9d78db40abd506e403e8e7da4dae4fc9c9fdf42a
File:CrazyflieTerminalRunProgram.png
6
34
89
2016-07-19T17:43:25Z
Jnoronha
3
Crazyflie Terminal showing the run .exe command
wikitext
text/x-wiki
Crazyflie Terminal showing the run .exe command
9d78db40abd506e403e8e7da4dae4fc9c9fdf42a
File:CrazyflieTerminalProgramStarted.png
6
35
90
2016-07-19T17:43:54Z
Jnoronha
3
Crazyflie Terminal showing Swarm Client ready for keyboard input
wikitext
text/x-wiki
Crazyflie Terminal showing Swarm Client ready for keyboard input
17a5d428fc8c01f3bab6f28028b083544f9dcd8d
File:CrazyflieTerminalKeyboardInput.png
6
36
91
2016-07-19T17:44:25Z
Jnoronha
3
Crazyflie Terminal showing Swarm Client after keyboard input has been pressed
wikitext
text/x-wiki
Crazyflie Terminal showing Swarm Client after keyboard input has been pressed
b1a82197fcc216cdc42515cc3ec6fff3bda23b0d
File:CrazyflieTerminalNoRadio.png
6
37
92
2016-07-19T17:44:54Z
Jnoronha
3
Crazyflie Terminal showing Error Garbage if no Radio plugged in.
wikitext
text/x-wiki
Crazyflie Terminal showing Error Garbage if no Radio plugged in.
b33575b3a31b2001e05e2cd3f58ccb1118990e3b
File:CrazyflieTerminalRadioDriverNotDeleted.png
6
38
93
2016-07-19T17:45:25Z
Jnoronha
3
Crazyflie Terminal showing Error if Radio Driver was not properly deleted. (Unplug and Re-plug Radio Dongle)
wikitext
text/x-wiki
Crazyflie Terminal showing Error if Radio Driver was not properly deleted. (Unplug and Re-plug Radio Dongle)
d0b2014bc578e0e9c5b8c64f7855eaf84ab407a5
Logging
0
39
98
2016-07-19T19:23:12Z
Jnoronha
3
Made intro and started init
wikitext
text/x-wiki
The logging system is the most important analysis tool we have.
This allows us to export any variable data we want out to an external text file. This way we can use any data processor to parse the data. (Excel, MATLAB, R, etc.)
==Initializing the Log Files==
We first need to initialize the log files and prepare them before each test.
:1. Create empty File Pointers
1c53d5e50c2bb45591030bf53d85899a7062d081
99
98
2016-07-19T19:56:18Z
Jnoronha
3
Added Using the log file code
wikitext
text/x-wiki
The logging system is the most important analysis tool we have.
This allows us to export any variable data we want out to an external text file. This way we can use any data processor to parse the data. (Excel, MATLAB, R, etc.)
==Creating and Using the Log Files==
We first need to initialize the log files and prepare them before each test.
:1. Create empty File Pointers (code in 'eris_vrpn.cpp')
<blockquote>
<code>
<pre>
FILE * outHand = NULL;
FILE * out1 = NULL;
FILE * out2 = NULL;
FILE * out3 = NULL;
FILE * out4 = NULL;
</pre>
</code>
</blockquote>
:2. Make sure Logging is Enabled (and Basic Logging if desired)
<blockquote>
<code>
<pre>
#define USE_VRPN 1
#define USE_KEYBOARD 1
#define USE_PRINTOUT 0
#define USE_LOGGING 1 <---//Enables Full Logging
#define USE_BASIC_LOGGING 1 <---//Only logs the necessities (FULL LOGGING MUST BE ENABLED FOR THIS TO WORK)
#define USE_PR_YAW_CORRECT 0
#define USE_HAND 1
</pre>
</code>
</blockquote>
:3. Create Log File Header (# = Log File Title, % = List of Variable Names, & = List of Variable Units)
::'''Note 1:''' This example is using BASIC_LOGGING 1,
::'''Note 2:''' Variables and units are separated by a double tab '\t\t' (Does not have to be '\t\t' any delimiter works)
<blockquote>
<code>
<pre>
const char * logHeaderHand = "#Hand Log File\n\
%Time\t\tPitch\t\tRoll\t\tYaw\t\tX\t\tY\t\tZ\t\tLoopTime\t\tLoopTimeDelta\n\
&sec\t\tdegrees\t\tdegrees\t\tdegrees\t\tmeters\t\tmeters\t\tmeters\t\tseconds\t\tseconds\n";
const char * logHeader1 = "#Crazyflie1 Log File\n\
%Time\t\tPitch\t\tRoll\t\tYaw\t\tX\t\tY\t\tZ\t\tCamYaw\t\tCorrectedYaw\t\tLoopTimeTotal\t\tLoopTimeTotalDelta\t\tLoopTime\t\tLoopTimeDelta\t\tvrpnPacketDelta\t\tvrpnPacketTime\t\tvrpnPacketBackup\t\tRadioRSSI\n\
&sec\t\tdegrees\t\tdegrees\t\tdegrees\t\tmeters\t\tmeters\t\tmeters\t\tdegrees\t\tdegrees\t\tseconds\t\tseconds\t\tseconds\t\tseconds\t\tseconds\t\tseconds\t\tpackets\t\tstrength\n";
const char * logHeader2 = "#Crazyflie2 Log File\n\
%Time\t\tPitch\t\tRoll\t\tYaw\t\tX\t\tY\t\tZ\t\tCamYaw\t\tCorrectedYaw\t\tLoopTimeTotal\t\tLoopTimeTotalDelta\t\tLoopTime\t\tLoopTimeDelta\t\tvrpnPacketDelta\t\tvrpnPacketTime\t\tvrpnPacketBackup\n\
&sec\t\tdegrees\t\tdegrees\t\tdegrees\t\tmeters\t\tmeters\t\tmeters\t\tdegrees\t\tdegrees\t\tseconds\t\tseconds\t\tseconds\t\tseconds\t\tseconds\t\tseconds\t\tpackets\n";
const char * logHeader3 = "#Crazyflie3 Log File\n\
%Time\t\tPitch\t\tRoll\t\tYaw\t\tX\t\tY\t\tZ\t\tCamYaw\t\tCorrectedYaw\t\tLoopTimeTotal\t\tLoopTimeTotalDelta\t\tLoopTime\t\tLoopTimeDelta\t\tvrpnPacketDelta\t\tvrpnPacketTime\t\tvrpnPacketBackup\n\
&sec\t\tdegrees\t\tdegrees\t\tdegrees\t\tmeters\t\tmeters\t\tmeters\t\tdegrees\t\tdegrees\t\tseconds\t\tseconds\t\tseconds\t\tseconds\t\tseconds\t\tseconds\t\tpackets\n";
const char * logHeader4 = "#Crazyflie4 Log File\n\
%Time\t\tPitch\t\tRoll\t\tYaw\t\tX\t\tY\t\tZ\t\tCamYaw\t\tCorrectedYaw\t\tLoopTimeTotal\t\tLoopTimeTotalDelta\t\tLoopTime\t\tLoopTimeDelta\t\tvrpnPacketDelta\t\tvrpnPacketTime\t\tvrpnPacketBackup\n\
&sec\t\tdegrees\t\tdegrees\t\tdegrees\t\tmeters\t\tmeters\t\tmeters\t\tdegrees\t\tdegrees\t\tseconds\t\tseconds\t\tseconds\t\tseconds\t\tseconds\t\tseconds\t\tpackets\n";
</pre>
</code>
</blockquote>
:4. Open External .txt file and Print Header into file
<blockquote>
<code>
<pre>
#if USE_HAND
outHand = fopen("hand.txt", "w"); //Opens text file with write permission
if(outHand == NULL)
{
printf("Could not open hand.log: errno %d\n", errno);
exit(-1);
}
fprintf(outHand, "%s\n", logHeaderHand); //Prints log header into corresponding file
#endif
if(cflieCopter1) //Checks to see if cflieCopter pointer has been initialized before opening file
{
out1 = fopen("cflie1.txt", "w");
if(out1 == NULL)
{
printf("Could not open cflie1.log: errno %d\n", errno);
exit(-1);
}
fprintf(out1, "%s\n", logHeader1);
}
if(cflieCopter2)
{
out2 = fopen("cflie2.txt", "w");
if(out2 == NULL)
{
printf("Could not open cflie2.log:errno %d\n", errno);
exit(-1);
}
fprintf(out2, "%s\n", logHeader2);
}
if(cflieCopter3)
{
out3 = fopen("cflie3.txt", "w");
if(out3 == NULL)
{
printf("Could not open cflie3.log:errno %d\n", errno);
exit(-1);
}
fprintf(out3, "%s\n", logHeader3);
}
if(cflieCopter4)
{
out4 = fopen("cflie4.txt", "w");
if(out4 == NULL)
{
printf("Could not open cflie4.log:errno %d\n", errno);
exit(-1);
}
fprintf(out4, "%s\n", logHeader4);
}
</pre>
</code>
</blockquote>
:5. Init has Completed (Start Program Loop)...
::'''Note 1:''' This code is run at the end of the Callback for each Crazyflie initialized (Executes once per new data packet)
::'''Note 2:''' This example is using BASIC_LOGGING, and is only showing Crazyflie1's code.
<blockquote>
<code>
<pre>
fprintf(out1, "%.6f\t\t", cflieCopter1->currentTime() - initTime1 );
fprintf(out1, "%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.6f\t\t%.6f\t\t%.6f\t\t%.6f\t\t%.6f\t\t%.6f\t\t%d\t\t%d",
cflieCopter1->roll(),
cflieCopter1->pitch(),
quadYaw1,
t.pos[0],
t.pos[1],
-t.pos[2],
camYawDeg1,
correctedYaw1,
loopTimeTotal,
loopTimeTotalDelta,
loopTime1,
loopTime1Delta,
vrpnPacketDelta1,
vrpnPacketTime1,
vrpnPacketBackup1,
cflieCopter1->radioRSSI());
fprintf(out1, "\n");
</pre>
</code>
</blockquote>
:6. Close External .txt files before ending program
<blockquote>
<code>
<pre>
#if USE_LOGGING
#if USE_HAND
fclose(outHand);
#endif
#if NUM_QUADS >= 1
fclose(out1);
#endif
#if NUM_QUADS >= 2
fclose(out2);
#endif
#if NUM_QUADS >= 3
fclose(out3);
#endif
#if NUM_QUADS >= 4
fclose(out4);
#endif
#endif
</pre>
</code>
</blockquote>
----
<center> '''Modifications Directory''' </center>
<center> [[Crazyflie Swarm|Crazyflie Swarm Home]] | [[Controller]] | [[Logging]] | [[Keyboard Commands]] | [[USB Radio#Changing Radio Channel|Changing Radio Channel]] | [[Flight Modes]] | [[Callbacks]] | [[Adding a Crazyflie]] | [[Firmware]] </center>
224ea4d9249e07642abed4628324c84513312f75
100
99
2016-07-19T19:57:14Z
Jnoronha
3
started matlab section
wikitext
text/x-wiki
The logging system is the most important analysis tool we have.
This allows us to export any variable data we want out to an external text file. This way we can use any data processor to parse the data. (Excel, MATLAB, R, etc.)
==Creating and Using the Log Files==
We first need to initialize the log files and prepare them before each test.
:1. Create empty File Pointers (code in 'eris_vrpn.cpp')
<blockquote>
<code>
<pre>
FILE * outHand = NULL;
FILE * out1 = NULL;
FILE * out2 = NULL;
FILE * out3 = NULL;
FILE * out4 = NULL;
</pre>
</code>
</blockquote>
:2. Make sure Logging is Enabled (and Basic Logging if desired)
<blockquote>
<code>
<pre>
#define USE_VRPN 1
#define USE_KEYBOARD 1
#define USE_PRINTOUT 0
#define USE_LOGGING 1 <---//Enables Full Logging
#define USE_BASIC_LOGGING 1 <---//Only logs the necessities (FULL LOGGING MUST BE ENABLED FOR THIS TO WORK)
#define USE_PR_YAW_CORRECT 0
#define USE_HAND 1
</pre>
</code>
</blockquote>
:3. Create Log File Header (# = Log File Title, % = List of Variable Names, & = List of Variable Units)
::'''Note 1:''' This example is using BASIC_LOGGING 1,
::'''Note 2:''' Variables and units are separated by a double tab '\t\t' (Does not have to be '\t\t' any delimiter works)
<blockquote>
<code>
<pre>
const char * logHeaderHand = "#Hand Log File\n\
%Time\t\tPitch\t\tRoll\t\tYaw\t\tX\t\tY\t\tZ\t\tLoopTime\t\tLoopTimeDelta\n\
&sec\t\tdegrees\t\tdegrees\t\tdegrees\t\tmeters\t\tmeters\t\tmeters\t\tseconds\t\tseconds\n";
const char * logHeader1 = "#Crazyflie1 Log File\n\
%Time\t\tPitch\t\tRoll\t\tYaw\t\tX\t\tY\t\tZ\t\tCamYaw\t\tCorrectedYaw\t\tLoopTimeTotal\t\tLoopTimeTotalDelta\t\tLoopTime\t\tLoopTimeDelta\t\tvrpnPacketDelta\t\tvrpnPacketTime\t\tvrpnPacketBackup\t\tRadioRSSI\n\
&sec\t\tdegrees\t\tdegrees\t\tdegrees\t\tmeters\t\tmeters\t\tmeters\t\tdegrees\t\tdegrees\t\tseconds\t\tseconds\t\tseconds\t\tseconds\t\tseconds\t\tseconds\t\tpackets\t\tstrength\n";
const char * logHeader2 = "#Crazyflie2 Log File\n\
%Time\t\tPitch\t\tRoll\t\tYaw\t\tX\t\tY\t\tZ\t\tCamYaw\t\tCorrectedYaw\t\tLoopTimeTotal\t\tLoopTimeTotalDelta\t\tLoopTime\t\tLoopTimeDelta\t\tvrpnPacketDelta\t\tvrpnPacketTime\t\tvrpnPacketBackup\n\
&sec\t\tdegrees\t\tdegrees\t\tdegrees\t\tmeters\t\tmeters\t\tmeters\t\tdegrees\t\tdegrees\t\tseconds\t\tseconds\t\tseconds\t\tseconds\t\tseconds\t\tseconds\t\tpackets\n";
const char * logHeader3 = "#Crazyflie3 Log File\n\
%Time\t\tPitch\t\tRoll\t\tYaw\t\tX\t\tY\t\tZ\t\tCamYaw\t\tCorrectedYaw\t\tLoopTimeTotal\t\tLoopTimeTotalDelta\t\tLoopTime\t\tLoopTimeDelta\t\tvrpnPacketDelta\t\tvrpnPacketTime\t\tvrpnPacketBackup\n\
&sec\t\tdegrees\t\tdegrees\t\tdegrees\t\tmeters\t\tmeters\t\tmeters\t\tdegrees\t\tdegrees\t\tseconds\t\tseconds\t\tseconds\t\tseconds\t\tseconds\t\tseconds\t\tpackets\n";
const char * logHeader4 = "#Crazyflie4 Log File\n\
%Time\t\tPitch\t\tRoll\t\tYaw\t\tX\t\tY\t\tZ\t\tCamYaw\t\tCorrectedYaw\t\tLoopTimeTotal\t\tLoopTimeTotalDelta\t\tLoopTime\t\tLoopTimeDelta\t\tvrpnPacketDelta\t\tvrpnPacketTime\t\tvrpnPacketBackup\n\
&sec\t\tdegrees\t\tdegrees\t\tdegrees\t\tmeters\t\tmeters\t\tmeters\t\tdegrees\t\tdegrees\t\tseconds\t\tseconds\t\tseconds\t\tseconds\t\tseconds\t\tseconds\t\tpackets\n";
</pre>
</code>
</blockquote>
:4. Open External .txt file and Print Header into file
<blockquote>
<code>
<pre>
#if USE_HAND
outHand = fopen("hand.txt", "w"); //Opens text file with write permission
if(outHand == NULL)
{
printf("Could not open hand.log: errno %d\n", errno);
exit(-1);
}
fprintf(outHand, "%s\n", logHeaderHand); //Prints log header into corresponding file
#endif
if(cflieCopter1) //Checks to see if cflieCopter pointer has been initialized before opening file
{
out1 = fopen("cflie1.txt", "w");
if(out1 == NULL)
{
printf("Could not open cflie1.log: errno %d\n", errno);
exit(-1);
}
fprintf(out1, "%s\n", logHeader1);
}
if(cflieCopter2)
{
out2 = fopen("cflie2.txt", "w");
if(out2 == NULL)
{
printf("Could not open cflie2.log:errno %d\n", errno);
exit(-1);
}
fprintf(out2, "%s\n", logHeader2);
}
if(cflieCopter3)
{
out3 = fopen("cflie3.txt", "w");
if(out3 == NULL)
{
printf("Could not open cflie3.log:errno %d\n", errno);
exit(-1);
}
fprintf(out3, "%s\n", logHeader3);
}
if(cflieCopter4)
{
out4 = fopen("cflie4.txt", "w");
if(out4 == NULL)
{
printf("Could not open cflie4.log:errno %d\n", errno);
exit(-1);
}
fprintf(out4, "%s\n", logHeader4);
}
</pre>
</code>
</blockquote>
:5. Init has Completed (Start Program Loop)...
::'''Note 1:''' This code is run at the end of the Callback for each Crazyflie initialized (Executes once per new data packet)
::'''Note 2:''' This example is using BASIC_LOGGING, and is only showing Crazyflie1's code.
<blockquote>
<code>
<pre>
fprintf(out1, "%.6f\t\t", cflieCopter1->currentTime() - initTime1 );
fprintf(out1, "%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.6f\t\t%.6f\t\t%.6f\t\t%.6f\t\t%.6f\t\t%.6f\t\t%d\t\t%d",
cflieCopter1->roll(),
cflieCopter1->pitch(),
quadYaw1,
t.pos[0],
t.pos[1],
-t.pos[2],
camYawDeg1,
correctedYaw1,
loopTimeTotal,
loopTimeTotalDelta,
loopTime1,
loopTime1Delta,
vrpnPacketDelta1,
vrpnPacketTime1,
vrpnPacketBackup1,
cflieCopter1->radioRSSI());
fprintf(out1, "\n");
</pre>
</code>
</blockquote>
:6. Close External .txt files before ending program
<blockquote>
<code>
<pre>
#if USE_LOGGING
#if USE_HAND
fclose(outHand);
#endif
#if NUM_QUADS >= 1
fclose(out1);
#endif
#if NUM_QUADS >= 2
fclose(out2);
#endif
#if NUM_QUADS >= 3
fclose(out3);
#endif
#if NUM_QUADS >= 4
fclose(out4);
#endif
#endif
</pre>
</code>
</blockquote>
==MATLAB Parser==
We use a Matlab script to parse the log files.
----
<center> '''Modifications Directory''' </center>
<center> [[Crazyflie Swarm|Crazyflie Swarm Home]] | [[Controller]] | [[Logging]] | [[Keyboard Commands]] | [[USB Radio#Changing Radio Channel|Changing Radio Channel]] | [[Flight Modes]] | [[Callbacks]] | [[Adding a Crazyflie]] | [[Firmware]] </center>
ca1550eb2539f2dcc779562e101a8d7b2d374cfd
Logging
0
39
101
100
2016-07-19T20:28:09Z
Jnoronha
3
wikitext
text/x-wiki
The logging system is the most important analysis tool we have.
This allows us to export any variable data we want out to an external text file. This way we can use any data processor to parse the data. (Excel, MATLAB, R, etc.)
==Creating and Using the Log Files==
We first need to initialize the log files and prepare them before each test.
:1. Create empty File Pointers (code in 'eris_vrpn.cpp')
<blockquote>
<code>
<pre>
FILE * outHand = NULL;
FILE * out1 = NULL;
FILE * out2 = NULL;
FILE * out3 = NULL;
FILE * out4 = NULL;
</pre>
</code>
</blockquote>
:2. Make sure Logging is Enabled (and Basic Logging if desired)
<blockquote>
<code>
<pre>
#define USE_VRPN 1
#define USE_KEYBOARD 1
#define USE_PRINTOUT 0
#define USE_LOGGING 1 <---//Enables Full Logging
#define USE_BASIC_LOGGING 1 <---//Only logs the necessities (FULL LOGGING MUST BE ENABLED FOR THIS TO WORK)
#define USE_PR_YAW_CORRECT 0
#define USE_HAND 1
</pre>
</code>
</blockquote>
:3. Create Log File Header (# = Log File Title, % = List of Variable Names, & = List of Variable Units)
::'''Note 1:''' This example is using BASIC_LOGGING 1,
::'''Note 2:''' Variables and units are separated by a double tab '\t\t' (Does not have to be '\t\t' any delimiter works)
<blockquote>
<code>
<pre>
const char * logHeaderHand = "#Hand Log File\n\
%Time\t\tPitch\t\tRoll\t\tYaw\t\tX\t\tY\t\tZ\t\tLoopTime\t\tLoopTimeDelta\n\
&sec\t\tdegrees\t\tdegrees\t\tdegrees\t\tmeters\t\tmeters\t\tmeters\t\tseconds\t\tseconds\n";
const char * logHeader1 = "#Crazyflie1 Log File\n\
%Time\t\tPitch\t\tRoll\t\tYaw\t\tX\t\tY\t\tZ\t\tCamYaw\t\tCorrectedYaw\t\tLoopTimeTotal\t\tLoopTimeTotalDelta\t\tLoopTime\t\tLoopTimeDelta\t\tvrpnPacketDelta\t\tvrpnPacketTime\t\tvrpnPacketBackup\t\tRadioRSSI\n\
&sec\t\tdegrees\t\tdegrees\t\tdegrees\t\tmeters\t\tmeters\t\tmeters\t\tdegrees\t\tdegrees\t\tseconds\t\tseconds\t\tseconds\t\tseconds\t\tseconds\t\tseconds\t\tpackets\t\tstrength\n";
const char * logHeader2 = "#Crazyflie2 Log File\n\
%Time\t\tPitch\t\tRoll\t\tYaw\t\tX\t\tY\t\tZ\t\tCamYaw\t\tCorrectedYaw\t\tLoopTimeTotal\t\tLoopTimeTotalDelta\t\tLoopTime\t\tLoopTimeDelta\t\tvrpnPacketDelta\t\tvrpnPacketTime\t\tvrpnPacketBackup\n\
&sec\t\tdegrees\t\tdegrees\t\tdegrees\t\tmeters\t\tmeters\t\tmeters\t\tdegrees\t\tdegrees\t\tseconds\t\tseconds\t\tseconds\t\tseconds\t\tseconds\t\tseconds\t\tpackets\n";
const char * logHeader3 = "#Crazyflie3 Log File\n\
%Time\t\tPitch\t\tRoll\t\tYaw\t\tX\t\tY\t\tZ\t\tCamYaw\t\tCorrectedYaw\t\tLoopTimeTotal\t\tLoopTimeTotalDelta\t\tLoopTime\t\tLoopTimeDelta\t\tvrpnPacketDelta\t\tvrpnPacketTime\t\tvrpnPacketBackup\n\
&sec\t\tdegrees\t\tdegrees\t\tdegrees\t\tmeters\t\tmeters\t\tmeters\t\tdegrees\t\tdegrees\t\tseconds\t\tseconds\t\tseconds\t\tseconds\t\tseconds\t\tseconds\t\tpackets\n";
const char * logHeader4 = "#Crazyflie4 Log File\n\
%Time\t\tPitch\t\tRoll\t\tYaw\t\tX\t\tY\t\tZ\t\tCamYaw\t\tCorrectedYaw\t\tLoopTimeTotal\t\tLoopTimeTotalDelta\t\tLoopTime\t\tLoopTimeDelta\t\tvrpnPacketDelta\t\tvrpnPacketTime\t\tvrpnPacketBackup\n\
&sec\t\tdegrees\t\tdegrees\t\tdegrees\t\tmeters\t\tmeters\t\tmeters\t\tdegrees\t\tdegrees\t\tseconds\t\tseconds\t\tseconds\t\tseconds\t\tseconds\t\tseconds\t\tpackets\n";
</pre>
</code>
</blockquote>
:4. Open External .txt file and Print Header into file
<blockquote>
<code>
<pre>
#if USE_HAND
outHand = fopen("hand.txt", "w"); //Opens text file with write permission
if(outHand == NULL)
{
printf("Could not open hand.log: errno %d\n", errno);
exit(-1);
}
fprintf(outHand, "%s\n", logHeaderHand); //Prints log header into corresponding file
#endif
if(cflieCopter1) //Checks to see if cflieCopter pointer has been initialized before opening file
{
out1 = fopen("cflie1.txt", "w");
if(out1 == NULL)
{
printf("Could not open cflie1.log: errno %d\n", errno);
exit(-1);
}
fprintf(out1, "%s\n", logHeader1);
}
if(cflieCopter2)
{
out2 = fopen("cflie2.txt", "w");
if(out2 == NULL)
{
printf("Could not open cflie2.log:errno %d\n", errno);
exit(-1);
}
fprintf(out2, "%s\n", logHeader2);
}
if(cflieCopter3)
{
out3 = fopen("cflie3.txt", "w");
if(out3 == NULL)
{
printf("Could not open cflie3.log:errno %d\n", errno);
exit(-1);
}
fprintf(out3, "%s\n", logHeader3);
}
if(cflieCopter4)
{
out4 = fopen("cflie4.txt", "w");
if(out4 == NULL)
{
printf("Could not open cflie4.log:errno %d\n", errno);
exit(-1);
}
fprintf(out4, "%s\n", logHeader4);
}
</pre>
</code>
</blockquote>
:5. Init has Completed (Start Program Loop) Prints Variable values to file...
::'''Note 1:''' This code is run at the end of the Callback for each Crazyflie initialized (Executes once per new data packet)
::'''Note 2:''' This example is using BASIC_LOGGING, and is only showing Crazyflie1's code.
<blockquote>
<code>
<pre>
fprintf(out1, "%.6f\t\t", cflieCopter1->currentTime() - initTime1 );
fprintf(out1, "%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.6f\t\t%.6f\t\t%.6f\t\t%.6f\t\t%.6f\t\t%.6f\t\t%d\t\t%d",
cflieCopter1->roll(),
cflieCopter1->pitch(),
quadYaw1,
t.pos[0],
t.pos[1],
-t.pos[2],
camYawDeg1,
correctedYaw1,
loopTimeTotal,
loopTimeTotalDelta,
loopTime1,
loopTime1Delta,
vrpnPacketDelta1,
vrpnPacketTime1,
vrpnPacketBackup1,
cflieCopter1->radioRSSI());
fprintf(out1, "\n");
</pre>
</code>
</blockquote>
:6. Close External .txt files before ending program
<blockquote>
<code>
<pre>
#if USE_LOGGING
#if USE_HAND
fclose(outHand);
#endif
#if NUM_QUADS >= 1
fclose(out1);
#endif
#if NUM_QUADS >= 2
fclose(out2);
#endif
#if NUM_QUADS >= 3
fclose(out3);
#endif
#if NUM_QUADS >= 4
fclose(out4);
#endif
#endif
</pre>
</code>
</blockquote>
==MATLAB Parser==
We use a Matlab script to parse the log files.
----
<center> '''Modifications Directory''' </center>
<center> [[Crazyflie Swarm|Crazyflie Swarm Home]] | [[Controller]] | [[Logging]] | [[Keyboard Commands]] | [[USB Radio#Changing Radio Channel|Changing Radio Channel]] | [[Flight Modes]] | [[Callbacks]] | [[Adding a Crazyflie]] | [[Firmware]] </center>
0afffe5819ef804c90f4eb5ba98a013f62828f45
103
101
2016-07-20T16:42:58Z
Jnoronha
3
Finished using logging in client
wikitext
text/x-wiki
The logging system is the most important analysis tool we have.
This allows us to export any variable data we want out to an external text file. This way we can use any data processor to parse the data. (Excel, MATLAB, R, etc.)
==Creating and Using the Log Files==
We first need to initialize the log files and prepare them before each test.
:1. Create empty File Pointers (code in 'eris_vrpn.cpp')
<blockquote>
<code>
<pre>
FILE * outHand = NULL;
FILE * out1 = NULL;
FILE * out2 = NULL;
FILE * out3 = NULL;
FILE * out4 = NULL;
</pre>
</code>
</blockquote>
:2. Make sure Logging is Enabled (and Basic Logging if desired)
<blockquote>
<code>
<pre>
#define USE_VRPN 1
#define USE_KEYBOARD 1
#define USE_PRINTOUT 0
#define USE_LOGGING 1 <---//Enables Full Logging
#define USE_BASIC_LOGGING 1 <---//Only logs the necessities (FULL LOGGING MUST BE ENABLED FOR THIS TO WORK)
#define USE_PR_YAW_CORRECT 0
#define USE_HAND 1
</pre>
</code>
</blockquote>
:3. Create Log File Header (# = Log File Title, % = List of Variable Names, & = List of Variable Units)
::'''Note 1:''' This example is using BASIC_LOGGING 1,
::'''Note 2:''' Variables and units are separated by a double tab '\t\t' (Does not have to be '\t\t' any delimiter works)
<blockquote>
<code>
<pre>
const char * logHeaderHand = "#Hand Log File\n\
%Time\t\tPitch\t\tRoll\t\tYaw\t\tX\t\tY\t\tZ\t\tLoopTime\t\tLoopTimeDelta\n\
&sec\t\tdegrees\t\tdegrees\t\tdegrees\t\tmeters\t\tmeters\t\tmeters\t\tseconds\t\tseconds\n";
const char * logHeader1 = "#Crazyflie1 Log File\n\
%Time\t\tPitch\t\tRoll\t\tYaw\t\tX\t\tY\t\tZ\t\tCamYaw\t\tCorrectedYaw\t\tLoopTimeTotal\t\tLoopTimeTotalDelta\t\tLoopTime\t\tLoopTimeDelta\t\tvrpnPacketDelta\t\tvrpnPacketTime\t\tvrpnPacketBackup\t\tRadioRSSI\n\
&sec\t\tdegrees\t\tdegrees\t\tdegrees\t\tmeters\t\tmeters\t\tmeters\t\tdegrees\t\tdegrees\t\tseconds\t\tseconds\t\tseconds\t\tseconds\t\tseconds\t\tseconds\t\tpackets\t\tstrength\n";
const char * logHeader2 = "#Crazyflie2 Log File\n\
%Time\t\tPitch\t\tRoll\t\tYaw\t\tX\t\tY\t\tZ\t\tCamYaw\t\tCorrectedYaw\t\tLoopTimeTotal\t\tLoopTimeTotalDelta\t\tLoopTime\t\tLoopTimeDelta\t\tvrpnPacketDelta\t\tvrpnPacketTime\t\tvrpnPacketBackup\n\
&sec\t\tdegrees\t\tdegrees\t\tdegrees\t\tmeters\t\tmeters\t\tmeters\t\tdegrees\t\tdegrees\t\tseconds\t\tseconds\t\tseconds\t\tseconds\t\tseconds\t\tseconds\t\tpackets\n";
const char * logHeader3 = "#Crazyflie3 Log File\n\
%Time\t\tPitch\t\tRoll\t\tYaw\t\tX\t\tY\t\tZ\t\tCamYaw\t\tCorrectedYaw\t\tLoopTimeTotal\t\tLoopTimeTotalDelta\t\tLoopTime\t\tLoopTimeDelta\t\tvrpnPacketDelta\t\tvrpnPacketTime\t\tvrpnPacketBackup\n\
&sec\t\tdegrees\t\tdegrees\t\tdegrees\t\tmeters\t\tmeters\t\tmeters\t\tdegrees\t\tdegrees\t\tseconds\t\tseconds\t\tseconds\t\tseconds\t\tseconds\t\tseconds\t\tpackets\n";
const char * logHeader4 = "#Crazyflie4 Log File\n\
%Time\t\tPitch\t\tRoll\t\tYaw\t\tX\t\tY\t\tZ\t\tCamYaw\t\tCorrectedYaw\t\tLoopTimeTotal\t\tLoopTimeTotalDelta\t\tLoopTime\t\tLoopTimeDelta\t\tvrpnPacketDelta\t\tvrpnPacketTime\t\tvrpnPacketBackup\n\
&sec\t\tdegrees\t\tdegrees\t\tdegrees\t\tmeters\t\tmeters\t\tmeters\t\tdegrees\t\tdegrees\t\tseconds\t\tseconds\t\tseconds\t\tseconds\t\tseconds\t\tseconds\t\tpackets\n";
</pre>
</code>
</blockquote>
:4. Open External .txt file and Print Header into file
<blockquote>
<code>
<pre>
#if USE_HAND
outHand = fopen("hand.txt", "w"); //Opens text file with write permission
if(outHand == NULL)
{
printf("Could not open hand.log: errno %d\n", errno);
exit(-1);
}
fprintf(outHand, "%s\n", logHeaderHand); //Prints log header into corresponding file
#endif
if(cflieCopter1) //Checks to see if cflieCopter pointer has been initialized before opening file
{
out1 = fopen("cflie1.txt", "w");
if(out1 == NULL)
{
printf("Could not open cflie1.log: errno %d\n", errno);
exit(-1);
}
fprintf(out1, "%s\n", logHeader1);
}
if(cflieCopter2)
{
out2 = fopen("cflie2.txt", "w");
if(out2 == NULL)
{
printf("Could not open cflie2.log:errno %d\n", errno);
exit(-1);
}
fprintf(out2, "%s\n", logHeader2);
}
if(cflieCopter3)
{
out3 = fopen("cflie3.txt", "w");
if(out3 == NULL)
{
printf("Could not open cflie3.log:errno %d\n", errno);
exit(-1);
}
fprintf(out3, "%s\n", logHeader3);
}
if(cflieCopter4)
{
out4 = fopen("cflie4.txt", "w");
if(out4 == NULL)
{
printf("Could not open cflie4.log:errno %d\n", errno);
exit(-1);
}
fprintf(out4, "%s\n", logHeader4);
}
</pre>
</code>
</blockquote>
:5. Init has Completed (Start Program Loop) Prints Variable values to file...
::'''Note 1:''' This code is run at the end of the Callback for each Crazyflie initialized (Executes once per new data packet)
::'''Note 2:''' This example is using BASIC_LOGGING, and is only showing Crazyflie1's code.
<blockquote>
<code>
<pre>
fprintf(out1, "%.6f\t\t", cflieCopter1->currentTime() - initTime1 );
fprintf(out1, "%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.6f\t\t%.6f\t\t%.6f\t\t%.6f\t\t%.6f\t\t%.6f\t\t%d\t\t%d",
cflieCopter1->roll(),
cflieCopter1->pitch(),
quadYaw1,
t.pos[0],
t.pos[1],
-t.pos[2],
camYawDeg1,
correctedYaw1,
loopTimeTotal,
loopTimeTotalDelta,
loopTime1,
loopTime1Delta,
vrpnPacketDelta1,
vrpnPacketTime1,
vrpnPacketBackup1,
cflieCopter1->radioRSSI());
fprintf(out1, "\n");
</pre>
</code>
</blockquote>
:6. Close External .txt files before ending program
<blockquote>
<code>
<pre>
#if USE_LOGGING
#if USE_HAND
fclose(outHand);
#endif
#if NUM_QUADS >= 1
fclose(out1);
#endif
#if NUM_QUADS >= 2
fclose(out2);
#endif
#if NUM_QUADS >= 3
fclose(out3);
#endif
#if NUM_QUADS >= 4
fclose(out4);
#endif
#endif
</pre>
</code>
</blockquote>
==MATLAB Parser==
We use a Matlab script to parse the log files.
==Starting New Log Blocks==
In the Swarm Client there is a sub-system designed for creating and maintaining Log Blocks. Once you have [[:Firmware#Log Blocks|created a new log block in the Firmware]] that you want to utilize we can do the following:
:1. Create an Enable function for the New Log Block (code in ''CCrazyflie.cpp'')
<blockquote>
<code>
<pre>
void CCrazyflie::enableMagnetometerLogging() {
m_tocLogs->registerLoggingBlock("magnetometer", 1000);
m_tocLogs->startLogging("mag.x", "magnetometer");
m_tocLogs->startLogging("mag.y", "magnetometer");
m_tocLogs->startLogging("mag.z", "magnetometer");
}
</pre>
</code>
</blockquote>
::This will then register a log block called ''magnetometer'' on the Client, which will be updated every 1000 &mus. It will then update the values listed in the block (X, Y, Z of the magnetometer).
::'''Note 1:''' The ''"mag.x"'' term must match the name defined in the Firmware log block (see [[:Firmware#Log Blocks|firmware example 1]])
::'''Note 2:''' The 2nd input to the ''startLogging'' function needs to match the name of the Client Log block we registered (in this case ''"magnetometer"'')
:2. Add the ''enableLogBlock'' function we just made to the list of Log blocks we want at startup (code in ''CCrazyflie.cpp''):
<blockquote>
<code>
<pre>
bool CCrazyflie::startLogging() {
// Register the desired sensor readings
this->enableStabilizerLogging();
// this->enableGyroscopeLogging();
// this->enableAccelerometerLogging();
this->enableBatteryLogging();
this->enableMagnetometerLogging(); <-----//This is the one we just made
// this->enableAltimeterLogging();
// this->enablePIDOutputLogging();
// this->enableRadioRSSILogging();
// this->enableMotorLogging();
return true;
}
</pre>
</code>
</blockquote>
::This ''startLogging'' function runs during Crazyflie startup and will start all the log blocks listed. As you can see we have some log blocks commented out currently so that we do NOT start those blocks.
:3. Create Functions to Read the variable values during runtime (code in ''CCrazyflie.cpp''):
<blockquote>
<code>
<pre>
float CCrazyflie::magX() {
return this->sensorDoubleValue("mag.x");
}
float CCrazyflie::magY() {
return this->sensorDoubleValue("mag.y");
}
float CCrazyflie::magZ() {
return this->sensorDoubleValue("mag.z");
}
</pre>
</code>
</blockquote>
::So now we can use these sensor values, from the Firmware, in the Client code with <code>magX1 = cflieCopter1->magX()</code>. This will store the sensor value in the Client-side variable ''magX1''.
:4. (OPTIONAL) We can also create a function to stop logging an individual log block in the Client (code in ''CCrazyflie.cpp'')
<blockquote>
<code>
<pre>
void CCrazyflie::disableMagnetometerLogging() {
m_tocLogs->unregisterLoggingBlock("magnetometer");
}
</pre>
</code>
</blockquote>
::This is straightforward, it just tells the client to stop logging this block.
:5. (OPTIONAL) And we can stop ALL log blocks in the client as well (code in ''CCrazyflie.cpp''):
<blockquote>
<code>
<pre>
bool CCrazyflie::stopLogging() {
this->disableStabilizerLogging();
this->disableGyroscopeLogging();
this->disableAccelerometerLogging();
this->disableBatteryLogging();
// this->disableMagnetometerLogging();
// this->disableAltimeterLogging();
// this->disablePIDOutputLogging();
this->disableRadioRSSILogging();
this->disableMotorLogging();
return true;
}
</pre>
</code>
</blockquote>
----
<center> '''Modifications Directory''' </center>
<center> [[Crazyflie Swarm|Crazyflie Swarm Home]] | [[Controller]] | [[Logging]] | [[Keyboard Commands]] | [[USB Radio#Changing Radio Channel|Changing Radio Channel]] | [[Flight Modes]] | [[Callbacks]] | [[Adding a Crazyflie]] | [[Firmware]] </center>
89ae9aa3b9ca4e268ea81ba481012c8779b59365
105
103
2016-07-20T16:47:36Z
Jnoronha
3
/* Starting New Log Blocks */ changed heading name
wikitext
text/x-wiki
The logging system is the most important analysis tool we have.
This allows us to export any variable data we want out to an external text file. This way we can use any data processor to parse the data. (Excel, MATLAB, R, etc.)
==Creating and Using the Log Files==
We first need to initialize the log files and prepare them before each test.
:1. Create empty File Pointers (code in 'eris_vrpn.cpp')
<blockquote>
<code>
<pre>
FILE * outHand = NULL;
FILE * out1 = NULL;
FILE * out2 = NULL;
FILE * out3 = NULL;
FILE * out4 = NULL;
</pre>
</code>
</blockquote>
:2. Make sure Logging is Enabled (and Basic Logging if desired)
<blockquote>
<code>
<pre>
#define USE_VRPN 1
#define USE_KEYBOARD 1
#define USE_PRINTOUT 0
#define USE_LOGGING 1 <---//Enables Full Logging
#define USE_BASIC_LOGGING 1 <---//Only logs the necessities (FULL LOGGING MUST BE ENABLED FOR THIS TO WORK)
#define USE_PR_YAW_CORRECT 0
#define USE_HAND 1
</pre>
</code>
</blockquote>
:3. Create Log File Header (# = Log File Title, % = List of Variable Names, & = List of Variable Units)
::'''Note 1:''' This example is using BASIC_LOGGING 1,
::'''Note 2:''' Variables and units are separated by a double tab '\t\t' (Does not have to be '\t\t' any delimiter works)
<blockquote>
<code>
<pre>
const char * logHeaderHand = "#Hand Log File\n\
%Time\t\tPitch\t\tRoll\t\tYaw\t\tX\t\tY\t\tZ\t\tLoopTime\t\tLoopTimeDelta\n\
&sec\t\tdegrees\t\tdegrees\t\tdegrees\t\tmeters\t\tmeters\t\tmeters\t\tseconds\t\tseconds\n";
const char * logHeader1 = "#Crazyflie1 Log File\n\
%Time\t\tPitch\t\tRoll\t\tYaw\t\tX\t\tY\t\tZ\t\tCamYaw\t\tCorrectedYaw\t\tLoopTimeTotal\t\tLoopTimeTotalDelta\t\tLoopTime\t\tLoopTimeDelta\t\tvrpnPacketDelta\t\tvrpnPacketTime\t\tvrpnPacketBackup\t\tRadioRSSI\n\
&sec\t\tdegrees\t\tdegrees\t\tdegrees\t\tmeters\t\tmeters\t\tmeters\t\tdegrees\t\tdegrees\t\tseconds\t\tseconds\t\tseconds\t\tseconds\t\tseconds\t\tseconds\t\tpackets\t\tstrength\n";
const char * logHeader2 = "#Crazyflie2 Log File\n\
%Time\t\tPitch\t\tRoll\t\tYaw\t\tX\t\tY\t\tZ\t\tCamYaw\t\tCorrectedYaw\t\tLoopTimeTotal\t\tLoopTimeTotalDelta\t\tLoopTime\t\tLoopTimeDelta\t\tvrpnPacketDelta\t\tvrpnPacketTime\t\tvrpnPacketBackup\n\
&sec\t\tdegrees\t\tdegrees\t\tdegrees\t\tmeters\t\tmeters\t\tmeters\t\tdegrees\t\tdegrees\t\tseconds\t\tseconds\t\tseconds\t\tseconds\t\tseconds\t\tseconds\t\tpackets\n";
const char * logHeader3 = "#Crazyflie3 Log File\n\
%Time\t\tPitch\t\tRoll\t\tYaw\t\tX\t\tY\t\tZ\t\tCamYaw\t\tCorrectedYaw\t\tLoopTimeTotal\t\tLoopTimeTotalDelta\t\tLoopTime\t\tLoopTimeDelta\t\tvrpnPacketDelta\t\tvrpnPacketTime\t\tvrpnPacketBackup\n\
&sec\t\tdegrees\t\tdegrees\t\tdegrees\t\tmeters\t\tmeters\t\tmeters\t\tdegrees\t\tdegrees\t\tseconds\t\tseconds\t\tseconds\t\tseconds\t\tseconds\t\tseconds\t\tpackets\n";
const char * logHeader4 = "#Crazyflie4 Log File\n\
%Time\t\tPitch\t\tRoll\t\tYaw\t\tX\t\tY\t\tZ\t\tCamYaw\t\tCorrectedYaw\t\tLoopTimeTotal\t\tLoopTimeTotalDelta\t\tLoopTime\t\tLoopTimeDelta\t\tvrpnPacketDelta\t\tvrpnPacketTime\t\tvrpnPacketBackup\n\
&sec\t\tdegrees\t\tdegrees\t\tdegrees\t\tmeters\t\tmeters\t\tmeters\t\tdegrees\t\tdegrees\t\tseconds\t\tseconds\t\tseconds\t\tseconds\t\tseconds\t\tseconds\t\tpackets\n";
</pre>
</code>
</blockquote>
:4. Open External .txt file and Print Header into file
<blockquote>
<code>
<pre>
#if USE_HAND
outHand = fopen("hand.txt", "w"); //Opens text file with write permission
if(outHand == NULL)
{
printf("Could not open hand.log: errno %d\n", errno);
exit(-1);
}
fprintf(outHand, "%s\n", logHeaderHand); //Prints log header into corresponding file
#endif
if(cflieCopter1) //Checks to see if cflieCopter pointer has been initialized before opening file
{
out1 = fopen("cflie1.txt", "w");
if(out1 == NULL)
{
printf("Could not open cflie1.log: errno %d\n", errno);
exit(-1);
}
fprintf(out1, "%s\n", logHeader1);
}
if(cflieCopter2)
{
out2 = fopen("cflie2.txt", "w");
if(out2 == NULL)
{
printf("Could not open cflie2.log:errno %d\n", errno);
exit(-1);
}
fprintf(out2, "%s\n", logHeader2);
}
if(cflieCopter3)
{
out3 = fopen("cflie3.txt", "w");
if(out3 == NULL)
{
printf("Could not open cflie3.log:errno %d\n", errno);
exit(-1);
}
fprintf(out3, "%s\n", logHeader3);
}
if(cflieCopter4)
{
out4 = fopen("cflie4.txt", "w");
if(out4 == NULL)
{
printf("Could not open cflie4.log:errno %d\n", errno);
exit(-1);
}
fprintf(out4, "%s\n", logHeader4);
}
</pre>
</code>
</blockquote>
:5. Init has Completed (Start Program Loop) Prints Variable values to file...
::'''Note 1:''' This code is run at the end of the Callback for each Crazyflie initialized (Executes once per new data packet)
::'''Note 2:''' This example is using BASIC_LOGGING, and is only showing Crazyflie1's code.
<blockquote>
<code>
<pre>
fprintf(out1, "%.6f\t\t", cflieCopter1->currentTime() - initTime1 );
fprintf(out1, "%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.6f\t\t%.6f\t\t%.6f\t\t%.6f\t\t%.6f\t\t%.6f\t\t%d\t\t%d",
cflieCopter1->roll(),
cflieCopter1->pitch(),
quadYaw1,
t.pos[0],
t.pos[1],
-t.pos[2],
camYawDeg1,
correctedYaw1,
loopTimeTotal,
loopTimeTotalDelta,
loopTime1,
loopTime1Delta,
vrpnPacketDelta1,
vrpnPacketTime1,
vrpnPacketBackup1,
cflieCopter1->radioRSSI());
fprintf(out1, "\n");
</pre>
</code>
</blockquote>
:6. Close External .txt files before ending program
<blockquote>
<code>
<pre>
#if USE_LOGGING
#if USE_HAND
fclose(outHand);
#endif
#if NUM_QUADS >= 1
fclose(out1);
#endif
#if NUM_QUADS >= 2
fclose(out2);
#endif
#if NUM_QUADS >= 3
fclose(out3);
#endif
#if NUM_QUADS >= 4
fclose(out4);
#endif
#endif
</pre>
</code>
</blockquote>
==MATLAB Parser==
We use a Matlab script to parse the log files.
==New Client Log Blocks==
In the Swarm Client there is a sub-system designed for creating and maintaining Log Blocks. Once you have [[:Firmware#Log Blocks|created a new log block in the Firmware]] that you want to utilize we can do the following:
:1. Create an Enable function for the New Log Block (code in ''CCrazyflie.cpp'')
<blockquote>
<code>
<pre>
void CCrazyflie::enableMagnetometerLogging() {
m_tocLogs->registerLoggingBlock("magnetometer", 1000);
m_tocLogs->startLogging("mag.x", "magnetometer");
m_tocLogs->startLogging("mag.y", "magnetometer");
m_tocLogs->startLogging("mag.z", "magnetometer");
}
</pre>
</code>
</blockquote>
::This will then register a log block called ''magnetometer'' on the Client, which will be updated every 1000 μs. It will then update the values listed in the block (X, Y, Z of the magnetometer).
::'''Note 1:''' The ''"mag.x"'' term must match the name defined in the Firmware log block (see [[:Firmware#Log Blocks|firmware example 1]])
::'''Note 2:''' The 2nd input to the ''startLogging'' function needs to match the name of the Client Log block we registered (in this case ''"magnetometer"'')
:2. Add the ''enableLogBlock'' function we just made to the list of Log blocks we want at startup (code in ''CCrazyflie.cpp''):
<blockquote>
<code>
<pre>
bool CCrazyflie::startLogging() {
// Register the desired sensor readings
this->enableStabilizerLogging();
// this->enableGyroscopeLogging();
// this->enableAccelerometerLogging();
this->enableBatteryLogging();
this->enableMagnetometerLogging(); <-----//This is the one we just made
// this->enableAltimeterLogging();
// this->enablePIDOutputLogging();
// this->enableRadioRSSILogging();
// this->enableMotorLogging();
return true;
}
</pre>
</code>
</blockquote>
::This ''startLogging'' function runs during Crazyflie startup and will start all the log blocks listed. As you can see we have some log blocks commented out currently so that we do NOT start those blocks.
:3. Create Functions to Read the variable values during runtime (code in ''CCrazyflie.cpp''):
<blockquote>
<code>
<pre>
float CCrazyflie::magX() {
return this->sensorDoubleValue("mag.x");
}
float CCrazyflie::magY() {
return this->sensorDoubleValue("mag.y");
}
float CCrazyflie::magZ() {
return this->sensorDoubleValue("mag.z");
}
</pre>
</code>
</blockquote>
::So now we can use these sensor values, from the Firmware, in the Client code with <code>magX1 = cflieCopter1->magX()</code>. This will store the sensor value in the Client-side variable ''magX1''.
:4. (OPTIONAL) We can also create a function to stop logging an individual log block in the Client (code in ''CCrazyflie.cpp'')
<blockquote>
<code>
<pre>
void CCrazyflie::disableMagnetometerLogging() {
m_tocLogs->unregisterLoggingBlock("magnetometer");
}
</pre>
</code>
</blockquote>
::This is straightforward, it just tells the client to stop logging this block.
:5. (OPTIONAL) And we can stop ALL log blocks in the client as well (code in ''CCrazyflie.cpp''):
<blockquote>
<code>
<pre>
bool CCrazyflie::stopLogging() {
this->disableStabilizerLogging();
this->disableGyroscopeLogging();
this->disableAccelerometerLogging();
this->disableBatteryLogging();
// this->disableMagnetometerLogging();
// this->disableAltimeterLogging();
// this->disablePIDOutputLogging();
this->disableRadioRSSILogging();
this->disableMotorLogging();
return true;
}
</pre>
</code>
</blockquote>
----
<center> '''Modifications Directory''' </center>
<center> [[Crazyflie Swarm|Crazyflie Swarm Home]] | [[Controller]] | [[Logging]] | [[Keyboard Commands]] | [[USB Radio#Changing Radio Channel|Changing Radio Channel]] | [[Flight Modes]] | [[Callbacks]] | [[Adding a Crazyflie]] | [[Firmware]] </center>
0e86c3b1b20fedde1d87d8f0292de22bfc02dda2
109
105
2016-07-20T17:58:47Z
Jnoronha
3
/* MATLAB Parser */ added reminder to finish
wikitext
text/x-wiki
The logging system is the most important analysis tool we have.
This allows us to export any variable data we want out to an external text file. This way we can use any data processor to parse the data. (Excel, MATLAB, R, etc.)
==Creating and Using the Log Files==
We first need to initialize the log files and prepare them before each test.
:1. Create empty File Pointers (code in 'eris_vrpn.cpp')
<blockquote>
<code>
<pre>
FILE * outHand = NULL;
FILE * out1 = NULL;
FILE * out2 = NULL;
FILE * out3 = NULL;
FILE * out4 = NULL;
</pre>
</code>
</blockquote>
:2. Make sure Logging is Enabled (and Basic Logging if desired)
<blockquote>
<code>
<pre>
#define USE_VRPN 1
#define USE_KEYBOARD 1
#define USE_PRINTOUT 0
#define USE_LOGGING 1 <---//Enables Full Logging
#define USE_BASIC_LOGGING 1 <---//Only logs the necessities (FULL LOGGING MUST BE ENABLED FOR THIS TO WORK)
#define USE_PR_YAW_CORRECT 0
#define USE_HAND 1
</pre>
</code>
</blockquote>
:3. Create Log File Header (# = Log File Title, % = List of Variable Names, & = List of Variable Units)
::'''Note 1:''' This example is using BASIC_LOGGING 1,
::'''Note 2:''' Variables and units are separated by a double tab '\t\t' (Does not have to be '\t\t' any delimiter works)
<blockquote>
<code>
<pre>
const char * logHeaderHand = "#Hand Log File\n\
%Time\t\tPitch\t\tRoll\t\tYaw\t\tX\t\tY\t\tZ\t\tLoopTime\t\tLoopTimeDelta\n\
&sec\t\tdegrees\t\tdegrees\t\tdegrees\t\tmeters\t\tmeters\t\tmeters\t\tseconds\t\tseconds\n";
const char * logHeader1 = "#Crazyflie1 Log File\n\
%Time\t\tPitch\t\tRoll\t\tYaw\t\tX\t\tY\t\tZ\t\tCamYaw\t\tCorrectedYaw\t\tLoopTimeTotal\t\tLoopTimeTotalDelta\t\tLoopTime\t\tLoopTimeDelta\t\tvrpnPacketDelta\t\tvrpnPacketTime\t\tvrpnPacketBackup\t\tRadioRSSI\n\
&sec\t\tdegrees\t\tdegrees\t\tdegrees\t\tmeters\t\tmeters\t\tmeters\t\tdegrees\t\tdegrees\t\tseconds\t\tseconds\t\tseconds\t\tseconds\t\tseconds\t\tseconds\t\tpackets\t\tstrength\n";
const char * logHeader2 = "#Crazyflie2 Log File\n\
%Time\t\tPitch\t\tRoll\t\tYaw\t\tX\t\tY\t\tZ\t\tCamYaw\t\tCorrectedYaw\t\tLoopTimeTotal\t\tLoopTimeTotalDelta\t\tLoopTime\t\tLoopTimeDelta\t\tvrpnPacketDelta\t\tvrpnPacketTime\t\tvrpnPacketBackup\n\
&sec\t\tdegrees\t\tdegrees\t\tdegrees\t\tmeters\t\tmeters\t\tmeters\t\tdegrees\t\tdegrees\t\tseconds\t\tseconds\t\tseconds\t\tseconds\t\tseconds\t\tseconds\t\tpackets\n";
const char * logHeader3 = "#Crazyflie3 Log File\n\
%Time\t\tPitch\t\tRoll\t\tYaw\t\tX\t\tY\t\tZ\t\tCamYaw\t\tCorrectedYaw\t\tLoopTimeTotal\t\tLoopTimeTotalDelta\t\tLoopTime\t\tLoopTimeDelta\t\tvrpnPacketDelta\t\tvrpnPacketTime\t\tvrpnPacketBackup\n\
&sec\t\tdegrees\t\tdegrees\t\tdegrees\t\tmeters\t\tmeters\t\tmeters\t\tdegrees\t\tdegrees\t\tseconds\t\tseconds\t\tseconds\t\tseconds\t\tseconds\t\tseconds\t\tpackets\n";
const char * logHeader4 = "#Crazyflie4 Log File\n\
%Time\t\tPitch\t\tRoll\t\tYaw\t\tX\t\tY\t\tZ\t\tCamYaw\t\tCorrectedYaw\t\tLoopTimeTotal\t\tLoopTimeTotalDelta\t\tLoopTime\t\tLoopTimeDelta\t\tvrpnPacketDelta\t\tvrpnPacketTime\t\tvrpnPacketBackup\n\
&sec\t\tdegrees\t\tdegrees\t\tdegrees\t\tmeters\t\tmeters\t\tmeters\t\tdegrees\t\tdegrees\t\tseconds\t\tseconds\t\tseconds\t\tseconds\t\tseconds\t\tseconds\t\tpackets\n";
</pre>
</code>
</blockquote>
:4. Open External .txt file and Print Header into file
<blockquote>
<code>
<pre>
#if USE_HAND
outHand = fopen("hand.txt", "w"); //Opens text file with write permission
if(outHand == NULL)
{
printf("Could not open hand.log: errno %d\n", errno);
exit(-1);
}
fprintf(outHand, "%s\n", logHeaderHand); //Prints log header into corresponding file
#endif
if(cflieCopter1) //Checks to see if cflieCopter pointer has been initialized before opening file
{
out1 = fopen("cflie1.txt", "w");
if(out1 == NULL)
{
printf("Could not open cflie1.log: errno %d\n", errno);
exit(-1);
}
fprintf(out1, "%s\n", logHeader1);
}
if(cflieCopter2)
{
out2 = fopen("cflie2.txt", "w");
if(out2 == NULL)
{
printf("Could not open cflie2.log:errno %d\n", errno);
exit(-1);
}
fprintf(out2, "%s\n", logHeader2);
}
if(cflieCopter3)
{
out3 = fopen("cflie3.txt", "w");
if(out3 == NULL)
{
printf("Could not open cflie3.log:errno %d\n", errno);
exit(-1);
}
fprintf(out3, "%s\n", logHeader3);
}
if(cflieCopter4)
{
out4 = fopen("cflie4.txt", "w");
if(out4 == NULL)
{
printf("Could not open cflie4.log:errno %d\n", errno);
exit(-1);
}
fprintf(out4, "%s\n", logHeader4);
}
</pre>
</code>
</blockquote>
:5. Init has Completed (Start Program Loop) Prints Variable values to file...
::'''Note 1:''' This code is run at the end of the Callback for each Crazyflie initialized (Executes once per new data packet)
::'''Note 2:''' This example is using BASIC_LOGGING, and is only showing Crazyflie1's code.
<blockquote>
<code>
<pre>
fprintf(out1, "%.6f\t\t", cflieCopter1->currentTime() - initTime1 );
fprintf(out1, "%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.6f\t\t%.6f\t\t%.6f\t\t%.6f\t\t%.6f\t\t%.6f\t\t%d\t\t%d",
cflieCopter1->roll(),
cflieCopter1->pitch(),
quadYaw1,
t.pos[0],
t.pos[1],
-t.pos[2],
camYawDeg1,
correctedYaw1,
loopTimeTotal,
loopTimeTotalDelta,
loopTime1,
loopTime1Delta,
vrpnPacketDelta1,
vrpnPacketTime1,
vrpnPacketBackup1,
cflieCopter1->radioRSSI());
fprintf(out1, "\n");
</pre>
</code>
</blockquote>
:6. Close External .txt files before ending program
<blockquote>
<code>
<pre>
#if USE_LOGGING
#if USE_HAND
fclose(outHand);
#endif
#if NUM_QUADS >= 1
fclose(out1);
#endif
#if NUM_QUADS >= 2
fclose(out2);
#endif
#if NUM_QUADS >= 3
fclose(out3);
#endif
#if NUM_QUADS >= 4
fclose(out4);
#endif
#endif
</pre>
</code>
</blockquote>
==MATLAB Parser (TODO)==
We use a Matlab script to parse the log files.
==New Client Log Blocks==
In the Swarm Client there is a sub-system designed for creating and maintaining Log Blocks. Once you have [[:Firmware#Log Blocks|created a new log block in the Firmware]] that you want to utilize we can do the following:
:1. Create an Enable function for the New Log Block (code in ''CCrazyflie.cpp'')
<blockquote>
<code>
<pre>
void CCrazyflie::enableMagnetometerLogging() {
m_tocLogs->registerLoggingBlock("magnetometer", 1000);
m_tocLogs->startLogging("mag.x", "magnetometer");
m_tocLogs->startLogging("mag.y", "magnetometer");
m_tocLogs->startLogging("mag.z", "magnetometer");
}
</pre>
</code>
</blockquote>
::This will then register a log block called ''magnetometer'' on the Client, which will be updated every 1000 μs. It will then update the values listed in the block (X, Y, Z of the magnetometer).
::'''Note 1:''' The ''"mag.x"'' term must match the name defined in the Firmware log block (see [[:Firmware#Log Blocks|firmware example 1]])
::'''Note 2:''' The 2nd input to the ''startLogging'' function needs to match the name of the Client Log block we registered (in this case ''"magnetometer"'')
:2. Add the ''enableLogBlock'' function we just made to the list of Log blocks we want at startup (code in ''CCrazyflie.cpp''):
<blockquote>
<code>
<pre>
bool CCrazyflie::startLogging() {
// Register the desired sensor readings
this->enableStabilizerLogging();
// this->enableGyroscopeLogging();
// this->enableAccelerometerLogging();
this->enableBatteryLogging();
this->enableMagnetometerLogging(); <-----//This is the one we just made
// this->enableAltimeterLogging();
// this->enablePIDOutputLogging();
// this->enableRadioRSSILogging();
// this->enableMotorLogging();
return true;
}
</pre>
</code>
</blockquote>
::This ''startLogging'' function runs during Crazyflie startup and will start all the log blocks listed. As you can see we have some log blocks commented out currently so that we do NOT start those blocks.
:3. Create Functions to Read the variable values during runtime (code in ''CCrazyflie.cpp''):
<blockquote>
<code>
<pre>
float CCrazyflie::magX() {
return this->sensorDoubleValue("mag.x");
}
float CCrazyflie::magY() {
return this->sensorDoubleValue("mag.y");
}
float CCrazyflie::magZ() {
return this->sensorDoubleValue("mag.z");
}
</pre>
</code>
</blockquote>
::So now we can use these sensor values, from the Firmware, in the Client code with <code>magX1 = cflieCopter1->magX()</code>. This will store the sensor value in the Client-side variable ''magX1''.
:4. (OPTIONAL) We can also create a function to stop logging an individual log block in the Client (code in ''CCrazyflie.cpp'')
<blockquote>
<code>
<pre>
void CCrazyflie::disableMagnetometerLogging() {
m_tocLogs->unregisterLoggingBlock("magnetometer");
}
</pre>
</code>
</blockquote>
::This is straightforward, it just tells the client to stop logging this block.
:5. (OPTIONAL) And we can stop ALL log blocks in the client as well (code in ''CCrazyflie.cpp''):
<blockquote>
<code>
<pre>
bool CCrazyflie::stopLogging() {
this->disableStabilizerLogging();
this->disableGyroscopeLogging();
this->disableAccelerometerLogging();
this->disableBatteryLogging();
// this->disableMagnetometerLogging();
// this->disableAltimeterLogging();
// this->disablePIDOutputLogging();
this->disableRadioRSSILogging();
this->disableMotorLogging();
return true;
}
</pre>
</code>
</blockquote>
----
<center> '''Modifications Directory''' </center>
<center> [[Crazyflie Swarm|Crazyflie Swarm Home]] | [[Controller]] | [[Logging]] | [[Keyboard Commands]] | [[USB Radio#Changing Radio Channel|Changing Radio Channel]] | [[Flight Modes]] | [[Callbacks]] | [[Adding a Crazyflie]] | [[Firmware]] </center>
cffcf9290c8d4c7e3257790700b6aaeb1b45ad54
110
109
2016-07-20T17:59:01Z
Jnoronha
3
/* MATLAB Parser (TODO) */
wikitext
text/x-wiki
The logging system is the most important analysis tool we have.
This allows us to export any variable data we want out to an external text file. This way we can use any data processor to parse the data. (Excel, MATLAB, R, etc.)
==Creating and Using the Log Files==
We first need to initialize the log files and prepare them before each test.
:1. Create empty File Pointers (code in 'eris_vrpn.cpp')
<blockquote>
<code>
<pre>
FILE * outHand = NULL;
FILE * out1 = NULL;
FILE * out2 = NULL;
FILE * out3 = NULL;
FILE * out4 = NULL;
</pre>
</code>
</blockquote>
:2. Make sure Logging is Enabled (and Basic Logging if desired)
<blockquote>
<code>
<pre>
#define USE_VRPN 1
#define USE_KEYBOARD 1
#define USE_PRINTOUT 0
#define USE_LOGGING 1 <---//Enables Full Logging
#define USE_BASIC_LOGGING 1 <---//Only logs the necessities (FULL LOGGING MUST BE ENABLED FOR THIS TO WORK)
#define USE_PR_YAW_CORRECT 0
#define USE_HAND 1
</pre>
</code>
</blockquote>
:3. Create Log File Header (# = Log File Title, % = List of Variable Names, & = List of Variable Units)
::'''Note 1:''' This example is using BASIC_LOGGING 1,
::'''Note 2:''' Variables and units are separated by a double tab '\t\t' (Does not have to be '\t\t' any delimiter works)
<blockquote>
<code>
<pre>
const char * logHeaderHand = "#Hand Log File\n\
%Time\t\tPitch\t\tRoll\t\tYaw\t\tX\t\tY\t\tZ\t\tLoopTime\t\tLoopTimeDelta\n\
&sec\t\tdegrees\t\tdegrees\t\tdegrees\t\tmeters\t\tmeters\t\tmeters\t\tseconds\t\tseconds\n";
const char * logHeader1 = "#Crazyflie1 Log File\n\
%Time\t\tPitch\t\tRoll\t\tYaw\t\tX\t\tY\t\tZ\t\tCamYaw\t\tCorrectedYaw\t\tLoopTimeTotal\t\tLoopTimeTotalDelta\t\tLoopTime\t\tLoopTimeDelta\t\tvrpnPacketDelta\t\tvrpnPacketTime\t\tvrpnPacketBackup\t\tRadioRSSI\n\
&sec\t\tdegrees\t\tdegrees\t\tdegrees\t\tmeters\t\tmeters\t\tmeters\t\tdegrees\t\tdegrees\t\tseconds\t\tseconds\t\tseconds\t\tseconds\t\tseconds\t\tseconds\t\tpackets\t\tstrength\n";
const char * logHeader2 = "#Crazyflie2 Log File\n\
%Time\t\tPitch\t\tRoll\t\tYaw\t\tX\t\tY\t\tZ\t\tCamYaw\t\tCorrectedYaw\t\tLoopTimeTotal\t\tLoopTimeTotalDelta\t\tLoopTime\t\tLoopTimeDelta\t\tvrpnPacketDelta\t\tvrpnPacketTime\t\tvrpnPacketBackup\n\
&sec\t\tdegrees\t\tdegrees\t\tdegrees\t\tmeters\t\tmeters\t\tmeters\t\tdegrees\t\tdegrees\t\tseconds\t\tseconds\t\tseconds\t\tseconds\t\tseconds\t\tseconds\t\tpackets\n";
const char * logHeader3 = "#Crazyflie3 Log File\n\
%Time\t\tPitch\t\tRoll\t\tYaw\t\tX\t\tY\t\tZ\t\tCamYaw\t\tCorrectedYaw\t\tLoopTimeTotal\t\tLoopTimeTotalDelta\t\tLoopTime\t\tLoopTimeDelta\t\tvrpnPacketDelta\t\tvrpnPacketTime\t\tvrpnPacketBackup\n\
&sec\t\tdegrees\t\tdegrees\t\tdegrees\t\tmeters\t\tmeters\t\tmeters\t\tdegrees\t\tdegrees\t\tseconds\t\tseconds\t\tseconds\t\tseconds\t\tseconds\t\tseconds\t\tpackets\n";
const char * logHeader4 = "#Crazyflie4 Log File\n\
%Time\t\tPitch\t\tRoll\t\tYaw\t\tX\t\tY\t\tZ\t\tCamYaw\t\tCorrectedYaw\t\tLoopTimeTotal\t\tLoopTimeTotalDelta\t\tLoopTime\t\tLoopTimeDelta\t\tvrpnPacketDelta\t\tvrpnPacketTime\t\tvrpnPacketBackup\n\
&sec\t\tdegrees\t\tdegrees\t\tdegrees\t\tmeters\t\tmeters\t\tmeters\t\tdegrees\t\tdegrees\t\tseconds\t\tseconds\t\tseconds\t\tseconds\t\tseconds\t\tseconds\t\tpackets\n";
</pre>
</code>
</blockquote>
:4. Open External .txt file and Print Header into file
<blockquote>
<code>
<pre>
#if USE_HAND
outHand = fopen("hand.txt", "w"); //Opens text file with write permission
if(outHand == NULL)
{
printf("Could not open hand.log: errno %d\n", errno);
exit(-1);
}
fprintf(outHand, "%s\n", logHeaderHand); //Prints log header into corresponding file
#endif
if(cflieCopter1) //Checks to see if cflieCopter pointer has been initialized before opening file
{
out1 = fopen("cflie1.txt", "w");
if(out1 == NULL)
{
printf("Could not open cflie1.log: errno %d\n", errno);
exit(-1);
}
fprintf(out1, "%s\n", logHeader1);
}
if(cflieCopter2)
{
out2 = fopen("cflie2.txt", "w");
if(out2 == NULL)
{
printf("Could not open cflie2.log:errno %d\n", errno);
exit(-1);
}
fprintf(out2, "%s\n", logHeader2);
}
if(cflieCopter3)
{
out3 = fopen("cflie3.txt", "w");
if(out3 == NULL)
{
printf("Could not open cflie3.log:errno %d\n", errno);
exit(-1);
}
fprintf(out3, "%s\n", logHeader3);
}
if(cflieCopter4)
{
out4 = fopen("cflie4.txt", "w");
if(out4 == NULL)
{
printf("Could not open cflie4.log:errno %d\n", errno);
exit(-1);
}
fprintf(out4, "%s\n", logHeader4);
}
</pre>
</code>
</blockquote>
:5. Init has Completed (Start Program Loop) Prints Variable values to file...
::'''Note 1:''' This code is run at the end of the Callback for each Crazyflie initialized (Executes once per new data packet)
::'''Note 2:''' This example is using BASIC_LOGGING, and is only showing Crazyflie1's code.
<blockquote>
<code>
<pre>
fprintf(out1, "%.6f\t\t", cflieCopter1->currentTime() - initTime1 );
fprintf(out1, "%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.6f\t\t%.6f\t\t%.6f\t\t%.6f\t\t%.6f\t\t%.6f\t\t%d\t\t%d",
cflieCopter1->roll(),
cflieCopter1->pitch(),
quadYaw1,
t.pos[0],
t.pos[1],
-t.pos[2],
camYawDeg1,
correctedYaw1,
loopTimeTotal,
loopTimeTotalDelta,
loopTime1,
loopTime1Delta,
vrpnPacketDelta1,
vrpnPacketTime1,
vrpnPacketBackup1,
cflieCopter1->radioRSSI());
fprintf(out1, "\n");
</pre>
</code>
</blockquote>
:6. Close External .txt files before ending program
<blockquote>
<code>
<pre>
#if USE_LOGGING
#if USE_HAND
fclose(outHand);
#endif
#if NUM_QUADS >= 1
fclose(out1);
#endif
#if NUM_QUADS >= 2
fclose(out2);
#endif
#if NUM_QUADS >= 3
fclose(out3);
#endif
#if NUM_QUADS >= 4
fclose(out4);
#endif
#endif
</pre>
</code>
</blockquote>
==MATLAB Parser (**TODO**)==
We use a Matlab script to parse the log files.
==New Client Log Blocks==
In the Swarm Client there is a sub-system designed for creating and maintaining Log Blocks. Once you have [[:Firmware#Log Blocks|created a new log block in the Firmware]] that you want to utilize we can do the following:
:1. Create an Enable function for the New Log Block (code in ''CCrazyflie.cpp'')
<blockquote>
<code>
<pre>
void CCrazyflie::enableMagnetometerLogging() {
m_tocLogs->registerLoggingBlock("magnetometer", 1000);
m_tocLogs->startLogging("mag.x", "magnetometer");
m_tocLogs->startLogging("mag.y", "magnetometer");
m_tocLogs->startLogging("mag.z", "magnetometer");
}
</pre>
</code>
</blockquote>
::This will then register a log block called ''magnetometer'' on the Client, which will be updated every 1000 μs. It will then update the values listed in the block (X, Y, Z of the magnetometer).
::'''Note 1:''' The ''"mag.x"'' term must match the name defined in the Firmware log block (see [[:Firmware#Log Blocks|firmware example 1]])
::'''Note 2:''' The 2nd input to the ''startLogging'' function needs to match the name of the Client Log block we registered (in this case ''"magnetometer"'')
:2. Add the ''enableLogBlock'' function we just made to the list of Log blocks we want at startup (code in ''CCrazyflie.cpp''):
<blockquote>
<code>
<pre>
bool CCrazyflie::startLogging() {
// Register the desired sensor readings
this->enableStabilizerLogging();
// this->enableGyroscopeLogging();
// this->enableAccelerometerLogging();
this->enableBatteryLogging();
this->enableMagnetometerLogging(); <-----//This is the one we just made
// this->enableAltimeterLogging();
// this->enablePIDOutputLogging();
// this->enableRadioRSSILogging();
// this->enableMotorLogging();
return true;
}
</pre>
</code>
</blockquote>
::This ''startLogging'' function runs during Crazyflie startup and will start all the log blocks listed. As you can see we have some log blocks commented out currently so that we do NOT start those blocks.
:3. Create Functions to Read the variable values during runtime (code in ''CCrazyflie.cpp''):
<blockquote>
<code>
<pre>
float CCrazyflie::magX() {
return this->sensorDoubleValue("mag.x");
}
float CCrazyflie::magY() {
return this->sensorDoubleValue("mag.y");
}
float CCrazyflie::magZ() {
return this->sensorDoubleValue("mag.z");
}
</pre>
</code>
</blockquote>
::So now we can use these sensor values, from the Firmware, in the Client code with <code>magX1 = cflieCopter1->magX()</code>. This will store the sensor value in the Client-side variable ''magX1''.
:4. (OPTIONAL) We can also create a function to stop logging an individual log block in the Client (code in ''CCrazyflie.cpp'')
<blockquote>
<code>
<pre>
void CCrazyflie::disableMagnetometerLogging() {
m_tocLogs->unregisterLoggingBlock("magnetometer");
}
</pre>
</code>
</blockquote>
::This is straightforward, it just tells the client to stop logging this block.
:5. (OPTIONAL) And we can stop ALL log blocks in the client as well (code in ''CCrazyflie.cpp''):
<blockquote>
<code>
<pre>
bool CCrazyflie::stopLogging() {
this->disableStabilizerLogging();
this->disableGyroscopeLogging();
this->disableAccelerometerLogging();
this->disableBatteryLogging();
// this->disableMagnetometerLogging();
// this->disableAltimeterLogging();
// this->disablePIDOutputLogging();
this->disableRadioRSSILogging();
this->disableMotorLogging();
return true;
}
</pre>
</code>
</blockquote>
----
<center> '''Modifications Directory''' </center>
<center> [[Crazyflie Swarm|Crazyflie Swarm Home]] | [[Controller]] | [[Logging]] | [[Keyboard Commands]] | [[USB Radio#Changing Radio Channel|Changing Radio Channel]] | [[Flight Modes]] | [[Callbacks]] | [[Adding a Crazyflie]] | [[Firmware]] </center>
52e0eb5cc25b70a5de627471f1b895dce6a5138a
111
110
2016-07-20T17:59:25Z
Jnoronha
3
/* MATLAB Parser (**TODO**) */ moved reminder to not the title
wikitext
text/x-wiki
The logging system is the most important analysis tool we have.
This allows us to export any variable data we want out to an external text file. This way we can use any data processor to parse the data. (Excel, MATLAB, R, etc.)
==Creating and Using the Log Files==
We first need to initialize the log files and prepare them before each test.
:1. Create empty File Pointers (code in 'eris_vrpn.cpp')
<blockquote>
<code>
<pre>
FILE * outHand = NULL;
FILE * out1 = NULL;
FILE * out2 = NULL;
FILE * out3 = NULL;
FILE * out4 = NULL;
</pre>
</code>
</blockquote>
:2. Make sure Logging is Enabled (and Basic Logging if desired)
<blockquote>
<code>
<pre>
#define USE_VRPN 1
#define USE_KEYBOARD 1
#define USE_PRINTOUT 0
#define USE_LOGGING 1 <---//Enables Full Logging
#define USE_BASIC_LOGGING 1 <---//Only logs the necessities (FULL LOGGING MUST BE ENABLED FOR THIS TO WORK)
#define USE_PR_YAW_CORRECT 0
#define USE_HAND 1
</pre>
</code>
</blockquote>
:3. Create Log File Header (# = Log File Title, % = List of Variable Names, & = List of Variable Units)
::'''Note 1:''' This example is using BASIC_LOGGING 1,
::'''Note 2:''' Variables and units are separated by a double tab '\t\t' (Does not have to be '\t\t' any delimiter works)
<blockquote>
<code>
<pre>
const char * logHeaderHand = "#Hand Log File\n\
%Time\t\tPitch\t\tRoll\t\tYaw\t\tX\t\tY\t\tZ\t\tLoopTime\t\tLoopTimeDelta\n\
&sec\t\tdegrees\t\tdegrees\t\tdegrees\t\tmeters\t\tmeters\t\tmeters\t\tseconds\t\tseconds\n";
const char * logHeader1 = "#Crazyflie1 Log File\n\
%Time\t\tPitch\t\tRoll\t\tYaw\t\tX\t\tY\t\tZ\t\tCamYaw\t\tCorrectedYaw\t\tLoopTimeTotal\t\tLoopTimeTotalDelta\t\tLoopTime\t\tLoopTimeDelta\t\tvrpnPacketDelta\t\tvrpnPacketTime\t\tvrpnPacketBackup\t\tRadioRSSI\n\
&sec\t\tdegrees\t\tdegrees\t\tdegrees\t\tmeters\t\tmeters\t\tmeters\t\tdegrees\t\tdegrees\t\tseconds\t\tseconds\t\tseconds\t\tseconds\t\tseconds\t\tseconds\t\tpackets\t\tstrength\n";
const char * logHeader2 = "#Crazyflie2 Log File\n\
%Time\t\tPitch\t\tRoll\t\tYaw\t\tX\t\tY\t\tZ\t\tCamYaw\t\tCorrectedYaw\t\tLoopTimeTotal\t\tLoopTimeTotalDelta\t\tLoopTime\t\tLoopTimeDelta\t\tvrpnPacketDelta\t\tvrpnPacketTime\t\tvrpnPacketBackup\n\
&sec\t\tdegrees\t\tdegrees\t\tdegrees\t\tmeters\t\tmeters\t\tmeters\t\tdegrees\t\tdegrees\t\tseconds\t\tseconds\t\tseconds\t\tseconds\t\tseconds\t\tseconds\t\tpackets\n";
const char * logHeader3 = "#Crazyflie3 Log File\n\
%Time\t\tPitch\t\tRoll\t\tYaw\t\tX\t\tY\t\tZ\t\tCamYaw\t\tCorrectedYaw\t\tLoopTimeTotal\t\tLoopTimeTotalDelta\t\tLoopTime\t\tLoopTimeDelta\t\tvrpnPacketDelta\t\tvrpnPacketTime\t\tvrpnPacketBackup\n\
&sec\t\tdegrees\t\tdegrees\t\tdegrees\t\tmeters\t\tmeters\t\tmeters\t\tdegrees\t\tdegrees\t\tseconds\t\tseconds\t\tseconds\t\tseconds\t\tseconds\t\tseconds\t\tpackets\n";
const char * logHeader4 = "#Crazyflie4 Log File\n\
%Time\t\tPitch\t\tRoll\t\tYaw\t\tX\t\tY\t\tZ\t\tCamYaw\t\tCorrectedYaw\t\tLoopTimeTotal\t\tLoopTimeTotalDelta\t\tLoopTime\t\tLoopTimeDelta\t\tvrpnPacketDelta\t\tvrpnPacketTime\t\tvrpnPacketBackup\n\
&sec\t\tdegrees\t\tdegrees\t\tdegrees\t\tmeters\t\tmeters\t\tmeters\t\tdegrees\t\tdegrees\t\tseconds\t\tseconds\t\tseconds\t\tseconds\t\tseconds\t\tseconds\t\tpackets\n";
</pre>
</code>
</blockquote>
:4. Open External .txt file and Print Header into file
<blockquote>
<code>
<pre>
#if USE_HAND
outHand = fopen("hand.txt", "w"); //Opens text file with write permission
if(outHand == NULL)
{
printf("Could not open hand.log: errno %d\n", errno);
exit(-1);
}
fprintf(outHand, "%s\n", logHeaderHand); //Prints log header into corresponding file
#endif
if(cflieCopter1) //Checks to see if cflieCopter pointer has been initialized before opening file
{
out1 = fopen("cflie1.txt", "w");
if(out1 == NULL)
{
printf("Could not open cflie1.log: errno %d\n", errno);
exit(-1);
}
fprintf(out1, "%s\n", logHeader1);
}
if(cflieCopter2)
{
out2 = fopen("cflie2.txt", "w");
if(out2 == NULL)
{
printf("Could not open cflie2.log:errno %d\n", errno);
exit(-1);
}
fprintf(out2, "%s\n", logHeader2);
}
if(cflieCopter3)
{
out3 = fopen("cflie3.txt", "w");
if(out3 == NULL)
{
printf("Could not open cflie3.log:errno %d\n", errno);
exit(-1);
}
fprintf(out3, "%s\n", logHeader3);
}
if(cflieCopter4)
{
out4 = fopen("cflie4.txt", "w");
if(out4 == NULL)
{
printf("Could not open cflie4.log:errno %d\n", errno);
exit(-1);
}
fprintf(out4, "%s\n", logHeader4);
}
</pre>
</code>
</blockquote>
:5. Init has Completed (Start Program Loop) Prints Variable values to file...
::'''Note 1:''' This code is run at the end of the Callback for each Crazyflie initialized (Executes once per new data packet)
::'''Note 2:''' This example is using BASIC_LOGGING, and is only showing Crazyflie1's code.
<blockquote>
<code>
<pre>
fprintf(out1, "%.6f\t\t", cflieCopter1->currentTime() - initTime1 );
fprintf(out1, "%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.6f\t\t%.6f\t\t%.6f\t\t%.6f\t\t%.6f\t\t%.6f\t\t%d\t\t%d",
cflieCopter1->roll(),
cflieCopter1->pitch(),
quadYaw1,
t.pos[0],
t.pos[1],
-t.pos[2],
camYawDeg1,
correctedYaw1,
loopTimeTotal,
loopTimeTotalDelta,
loopTime1,
loopTime1Delta,
vrpnPacketDelta1,
vrpnPacketTime1,
vrpnPacketBackup1,
cflieCopter1->radioRSSI());
fprintf(out1, "\n");
</pre>
</code>
</blockquote>
:6. Close External .txt files before ending program
<blockquote>
<code>
<pre>
#if USE_LOGGING
#if USE_HAND
fclose(outHand);
#endif
#if NUM_QUADS >= 1
fclose(out1);
#endif
#if NUM_QUADS >= 2
fclose(out2);
#endif
#if NUM_QUADS >= 3
fclose(out3);
#endif
#if NUM_QUADS >= 4
fclose(out4);
#endif
#endif
</pre>
</code>
</blockquote>
==MATLAB Parser==
'''(**TODO**)'''
We use a Matlab script to parse the log files.
==New Client Log Blocks==
In the Swarm Client there is a sub-system designed for creating and maintaining Log Blocks. Once you have [[:Firmware#Log Blocks|created a new log block in the Firmware]] that you want to utilize we can do the following:
:1. Create an Enable function for the New Log Block (code in ''CCrazyflie.cpp'')
<blockquote>
<code>
<pre>
void CCrazyflie::enableMagnetometerLogging() {
m_tocLogs->registerLoggingBlock("magnetometer", 1000);
m_tocLogs->startLogging("mag.x", "magnetometer");
m_tocLogs->startLogging("mag.y", "magnetometer");
m_tocLogs->startLogging("mag.z", "magnetometer");
}
</pre>
</code>
</blockquote>
::This will then register a log block called ''magnetometer'' on the Client, which will be updated every 1000 μs. It will then update the values listed in the block (X, Y, Z of the magnetometer).
::'''Note 1:''' The ''"mag.x"'' term must match the name defined in the Firmware log block (see [[:Firmware#Log Blocks|firmware example 1]])
::'''Note 2:''' The 2nd input to the ''startLogging'' function needs to match the name of the Client Log block we registered (in this case ''"magnetometer"'')
:2. Add the ''enableLogBlock'' function we just made to the list of Log blocks we want at startup (code in ''CCrazyflie.cpp''):
<blockquote>
<code>
<pre>
bool CCrazyflie::startLogging() {
// Register the desired sensor readings
this->enableStabilizerLogging();
// this->enableGyroscopeLogging();
// this->enableAccelerometerLogging();
this->enableBatteryLogging();
this->enableMagnetometerLogging(); <-----//This is the one we just made
// this->enableAltimeterLogging();
// this->enablePIDOutputLogging();
// this->enableRadioRSSILogging();
// this->enableMotorLogging();
return true;
}
</pre>
</code>
</blockquote>
::This ''startLogging'' function runs during Crazyflie startup and will start all the log blocks listed. As you can see we have some log blocks commented out currently so that we do NOT start those blocks.
:3. Create Functions to Read the variable values during runtime (code in ''CCrazyflie.cpp''):
<blockquote>
<code>
<pre>
float CCrazyflie::magX() {
return this->sensorDoubleValue("mag.x");
}
float CCrazyflie::magY() {
return this->sensorDoubleValue("mag.y");
}
float CCrazyflie::magZ() {
return this->sensorDoubleValue("mag.z");
}
</pre>
</code>
</blockquote>
::So now we can use these sensor values, from the Firmware, in the Client code with <code>magX1 = cflieCopter1->magX()</code>. This will store the sensor value in the Client-side variable ''magX1''.
:4. (OPTIONAL) We can also create a function to stop logging an individual log block in the Client (code in ''CCrazyflie.cpp'')
<blockquote>
<code>
<pre>
void CCrazyflie::disableMagnetometerLogging() {
m_tocLogs->unregisterLoggingBlock("magnetometer");
}
</pre>
</code>
</blockquote>
::This is straightforward, it just tells the client to stop logging this block.
:5. (OPTIONAL) And we can stop ALL log blocks in the client as well (code in ''CCrazyflie.cpp''):
<blockquote>
<code>
<pre>
bool CCrazyflie::stopLogging() {
this->disableStabilizerLogging();
this->disableGyroscopeLogging();
this->disableAccelerometerLogging();
this->disableBatteryLogging();
// this->disableMagnetometerLogging();
// this->disableAltimeterLogging();
// this->disablePIDOutputLogging();
this->disableRadioRSSILogging();
this->disableMotorLogging();
return true;
}
</pre>
</code>
</blockquote>
----
<center> '''Modifications Directory''' </center>
<center> [[Crazyflie Swarm|Crazyflie Swarm Home]] | [[Controller]] | [[Logging]] | [[Keyboard Commands]] | [[USB Radio#Changing Radio Channel|Changing Radio Channel]] | [[Flight Modes]] | [[Callbacks]] | [[Adding a Crazyflie]] | [[Firmware]] </center>
f9ecb3bf2212ee7f5f2affd41c39342d92faa84c
112
111
2016-07-20T18:00:29Z
Jnoronha
3
/* New Client Log Blocks */ short description
wikitext
text/x-wiki
The logging system is the most important analysis tool we have.
This allows us to export any variable data we want out to an external text file. This way we can use any data processor to parse the data. (Excel, MATLAB, R, etc.)
==Creating and Using the Log Files==
We first need to initialize the log files and prepare them before each test.
:1. Create empty File Pointers (code in 'eris_vrpn.cpp')
<blockquote>
<code>
<pre>
FILE * outHand = NULL;
FILE * out1 = NULL;
FILE * out2 = NULL;
FILE * out3 = NULL;
FILE * out4 = NULL;
</pre>
</code>
</blockquote>
:2. Make sure Logging is Enabled (and Basic Logging if desired)
<blockquote>
<code>
<pre>
#define USE_VRPN 1
#define USE_KEYBOARD 1
#define USE_PRINTOUT 0
#define USE_LOGGING 1 <---//Enables Full Logging
#define USE_BASIC_LOGGING 1 <---//Only logs the necessities (FULL LOGGING MUST BE ENABLED FOR THIS TO WORK)
#define USE_PR_YAW_CORRECT 0
#define USE_HAND 1
</pre>
</code>
</blockquote>
:3. Create Log File Header (# = Log File Title, % = List of Variable Names, & = List of Variable Units)
::'''Note 1:''' This example is using BASIC_LOGGING 1,
::'''Note 2:''' Variables and units are separated by a double tab '\t\t' (Does not have to be '\t\t' any delimiter works)
<blockquote>
<code>
<pre>
const char * logHeaderHand = "#Hand Log File\n\
%Time\t\tPitch\t\tRoll\t\tYaw\t\tX\t\tY\t\tZ\t\tLoopTime\t\tLoopTimeDelta\n\
&sec\t\tdegrees\t\tdegrees\t\tdegrees\t\tmeters\t\tmeters\t\tmeters\t\tseconds\t\tseconds\n";
const char * logHeader1 = "#Crazyflie1 Log File\n\
%Time\t\tPitch\t\tRoll\t\tYaw\t\tX\t\tY\t\tZ\t\tCamYaw\t\tCorrectedYaw\t\tLoopTimeTotal\t\tLoopTimeTotalDelta\t\tLoopTime\t\tLoopTimeDelta\t\tvrpnPacketDelta\t\tvrpnPacketTime\t\tvrpnPacketBackup\t\tRadioRSSI\n\
&sec\t\tdegrees\t\tdegrees\t\tdegrees\t\tmeters\t\tmeters\t\tmeters\t\tdegrees\t\tdegrees\t\tseconds\t\tseconds\t\tseconds\t\tseconds\t\tseconds\t\tseconds\t\tpackets\t\tstrength\n";
const char * logHeader2 = "#Crazyflie2 Log File\n\
%Time\t\tPitch\t\tRoll\t\tYaw\t\tX\t\tY\t\tZ\t\tCamYaw\t\tCorrectedYaw\t\tLoopTimeTotal\t\tLoopTimeTotalDelta\t\tLoopTime\t\tLoopTimeDelta\t\tvrpnPacketDelta\t\tvrpnPacketTime\t\tvrpnPacketBackup\n\
&sec\t\tdegrees\t\tdegrees\t\tdegrees\t\tmeters\t\tmeters\t\tmeters\t\tdegrees\t\tdegrees\t\tseconds\t\tseconds\t\tseconds\t\tseconds\t\tseconds\t\tseconds\t\tpackets\n";
const char * logHeader3 = "#Crazyflie3 Log File\n\
%Time\t\tPitch\t\tRoll\t\tYaw\t\tX\t\tY\t\tZ\t\tCamYaw\t\tCorrectedYaw\t\tLoopTimeTotal\t\tLoopTimeTotalDelta\t\tLoopTime\t\tLoopTimeDelta\t\tvrpnPacketDelta\t\tvrpnPacketTime\t\tvrpnPacketBackup\n\
&sec\t\tdegrees\t\tdegrees\t\tdegrees\t\tmeters\t\tmeters\t\tmeters\t\tdegrees\t\tdegrees\t\tseconds\t\tseconds\t\tseconds\t\tseconds\t\tseconds\t\tseconds\t\tpackets\n";
const char * logHeader4 = "#Crazyflie4 Log File\n\
%Time\t\tPitch\t\tRoll\t\tYaw\t\tX\t\tY\t\tZ\t\tCamYaw\t\tCorrectedYaw\t\tLoopTimeTotal\t\tLoopTimeTotalDelta\t\tLoopTime\t\tLoopTimeDelta\t\tvrpnPacketDelta\t\tvrpnPacketTime\t\tvrpnPacketBackup\n\
&sec\t\tdegrees\t\tdegrees\t\tdegrees\t\tmeters\t\tmeters\t\tmeters\t\tdegrees\t\tdegrees\t\tseconds\t\tseconds\t\tseconds\t\tseconds\t\tseconds\t\tseconds\t\tpackets\n";
</pre>
</code>
</blockquote>
:4. Open External .txt file and Print Header into file
<blockquote>
<code>
<pre>
#if USE_HAND
outHand = fopen("hand.txt", "w"); //Opens text file with write permission
if(outHand == NULL)
{
printf("Could not open hand.log: errno %d\n", errno);
exit(-1);
}
fprintf(outHand, "%s\n", logHeaderHand); //Prints log header into corresponding file
#endif
if(cflieCopter1) //Checks to see if cflieCopter pointer has been initialized before opening file
{
out1 = fopen("cflie1.txt", "w");
if(out1 == NULL)
{
printf("Could not open cflie1.log: errno %d\n", errno);
exit(-1);
}
fprintf(out1, "%s\n", logHeader1);
}
if(cflieCopter2)
{
out2 = fopen("cflie2.txt", "w");
if(out2 == NULL)
{
printf("Could not open cflie2.log:errno %d\n", errno);
exit(-1);
}
fprintf(out2, "%s\n", logHeader2);
}
if(cflieCopter3)
{
out3 = fopen("cflie3.txt", "w");
if(out3 == NULL)
{
printf("Could not open cflie3.log:errno %d\n", errno);
exit(-1);
}
fprintf(out3, "%s\n", logHeader3);
}
if(cflieCopter4)
{
out4 = fopen("cflie4.txt", "w");
if(out4 == NULL)
{
printf("Could not open cflie4.log:errno %d\n", errno);
exit(-1);
}
fprintf(out4, "%s\n", logHeader4);
}
</pre>
</code>
</blockquote>
:5. Init has Completed (Start Program Loop) Prints Variable values to file...
::'''Note 1:''' This code is run at the end of the Callback for each Crazyflie initialized (Executes once per new data packet)
::'''Note 2:''' This example is using BASIC_LOGGING, and is only showing Crazyflie1's code.
<blockquote>
<code>
<pre>
fprintf(out1, "%.6f\t\t", cflieCopter1->currentTime() - initTime1 );
fprintf(out1, "%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.6f\t\t%.6f\t\t%.6f\t\t%.6f\t\t%.6f\t\t%.6f\t\t%d\t\t%d",
cflieCopter1->roll(),
cflieCopter1->pitch(),
quadYaw1,
t.pos[0],
t.pos[1],
-t.pos[2],
camYawDeg1,
correctedYaw1,
loopTimeTotal,
loopTimeTotalDelta,
loopTime1,
loopTime1Delta,
vrpnPacketDelta1,
vrpnPacketTime1,
vrpnPacketBackup1,
cflieCopter1->radioRSSI());
fprintf(out1, "\n");
</pre>
</code>
</blockquote>
:6. Close External .txt files before ending program
<blockquote>
<code>
<pre>
#if USE_LOGGING
#if USE_HAND
fclose(outHand);
#endif
#if NUM_QUADS >= 1
fclose(out1);
#endif
#if NUM_QUADS >= 2
fclose(out2);
#endif
#if NUM_QUADS >= 3
fclose(out3);
#endif
#if NUM_QUADS >= 4
fclose(out4);
#endif
#endif
</pre>
</code>
</blockquote>
==MATLAB Parser==
'''(**TODO**)'''
We use a Matlab script to parse the log files.
==New Client Log Blocks==
In the Swarm Client there is a sub-system designed for creating and maintaining Log Blocks. Once you have [[:Firmware#Log Blocks|created a new log block in the Firmware]] that you want to utilize we can do the following:
:1. Create an Enable function for the New Log Block (code in ''CCrazyflie.cpp'')
<blockquote>
<code>
<pre>
void CCrazyflie::enableMagnetometerLogging() {
m_tocLogs->registerLoggingBlock("magnetometer", 1000);
m_tocLogs->startLogging("mag.x", "magnetometer");
m_tocLogs->startLogging("mag.y", "magnetometer");
m_tocLogs->startLogging("mag.z", "magnetometer");
}
</pre>
</code>
</blockquote>
::This will then register a log block called ''magnetometer'' on the Client, which will be updated every 1000 μs. It will then update the values listed in the block (X, Y, Z of the magnetometer).
::'''Note 1:''' The ''"mag.x"'' term must match the name defined in the Firmware log block (see [[:Firmware#Log Blocks|firmware example 1]])
::'''Note 2:''' The 2nd input to the ''startLogging'' function needs to match the name of the Client Log block we registered (in this case ''"magnetometer"'')
:2. Add the ''enableLogBlock'' function we just made to the list of Log blocks we want at startup (code in ''CCrazyflie.cpp''):
<blockquote>
<code>
<pre>
bool CCrazyflie::startLogging() {
// Register the desired sensor readings
this->enableStabilizerLogging();
// this->enableGyroscopeLogging();
// this->enableAccelerometerLogging();
this->enableBatteryLogging();
this->enableMagnetometerLogging(); <-----//This is the one we just made
// this->enableAltimeterLogging();
// this->enablePIDOutputLogging();
// this->enableRadioRSSILogging();
// this->enableMotorLogging();
return true;
}
</pre>
</code>
</blockquote>
::This ''startLogging'' function runs during Crazyflie startup and will start all the log blocks listed. As you can see we have some log blocks commented out currently so that we do NOT start those blocks.
:3. Create Functions to Read the variable values during runtime (code in ''CCrazyflie.cpp''):
<blockquote>
<code>
<pre>
float CCrazyflie::magX() {
return this->sensorDoubleValue("mag.x");
}
float CCrazyflie::magY() {
return this->sensorDoubleValue("mag.y");
}
float CCrazyflie::magZ() {
return this->sensorDoubleValue("mag.z");
}
</pre>
</code>
</blockquote>
::So now we can use these sensor values, from the Firmware, in the Client code with <code>magX1 = cflieCopter1->magX()</code>. This will store the sensor value in the Client-side variable ''magX1''.
:4. (OPTIONAL) We can also create a function to stop logging an individual log block in the Client (code in ''CCrazyflie.cpp'')
<blockquote>
<code>
<pre>
void CCrazyflie::disableMagnetometerLogging() {
m_tocLogs->unregisterLoggingBlock("magnetometer");
}
</pre>
</code>
</blockquote>
::This is straightforward, it just tells the client to stop logging this block.
:5. (OPTIONAL) And we can stop ALL log blocks in the client as well (code in ''CCrazyflie.cpp''):
<blockquote>
<code>
<pre>
bool CCrazyflie::stopLogging() {
this->disableStabilizerLogging();
this->disableGyroscopeLogging();
this->disableAccelerometerLogging();
this->disableBatteryLogging();
// this->disableMagnetometerLogging();
// this->disableAltimeterLogging();
// this->disablePIDOutputLogging();
this->disableRadioRSSILogging();
this->disableMotorLogging();
return true;
}
</pre>
</code>
</blockquote>
::This will disable ALL the logging blocks included in the list.
----
<center> '''Modifications Directory''' </center>
<center> [[Crazyflie Swarm|Crazyflie Swarm Home]] | [[Controller]] | [[Logging]] | [[Keyboard Commands]] | [[USB Radio#Changing Radio Channel|Changing Radio Channel]] | [[Flight Modes]] | [[Callbacks]] | [[Adding a Crazyflie]] | [[Firmware]] </center>
e70cdfb00d153e69dd85c031913ec6919410ad4c
113
112
2016-07-20T18:01:32Z
Jnoronha
3
/* New Client Log Blocks */ added space between directory and wiki page
wikitext
text/x-wiki
The logging system is the most important analysis tool we have.
This allows us to export any variable data we want out to an external text file. This way we can use any data processor to parse the data. (Excel, MATLAB, R, etc.)
==Creating and Using the Log Files==
We first need to initialize the log files and prepare them before each test.
:1. Create empty File Pointers (code in 'eris_vrpn.cpp')
<blockquote>
<code>
<pre>
FILE * outHand = NULL;
FILE * out1 = NULL;
FILE * out2 = NULL;
FILE * out3 = NULL;
FILE * out4 = NULL;
</pre>
</code>
</blockquote>
:2. Make sure Logging is Enabled (and Basic Logging if desired)
<blockquote>
<code>
<pre>
#define USE_VRPN 1
#define USE_KEYBOARD 1
#define USE_PRINTOUT 0
#define USE_LOGGING 1 <---//Enables Full Logging
#define USE_BASIC_LOGGING 1 <---//Only logs the necessities (FULL LOGGING MUST BE ENABLED FOR THIS TO WORK)
#define USE_PR_YAW_CORRECT 0
#define USE_HAND 1
</pre>
</code>
</blockquote>
:3. Create Log File Header (# = Log File Title, % = List of Variable Names, & = List of Variable Units)
::'''Note 1:''' This example is using BASIC_LOGGING 1,
::'''Note 2:''' Variables and units are separated by a double tab '\t\t' (Does not have to be '\t\t' any delimiter works)
<blockquote>
<code>
<pre>
const char * logHeaderHand = "#Hand Log File\n\
%Time\t\tPitch\t\tRoll\t\tYaw\t\tX\t\tY\t\tZ\t\tLoopTime\t\tLoopTimeDelta\n\
&sec\t\tdegrees\t\tdegrees\t\tdegrees\t\tmeters\t\tmeters\t\tmeters\t\tseconds\t\tseconds\n";
const char * logHeader1 = "#Crazyflie1 Log File\n\
%Time\t\tPitch\t\tRoll\t\tYaw\t\tX\t\tY\t\tZ\t\tCamYaw\t\tCorrectedYaw\t\tLoopTimeTotal\t\tLoopTimeTotalDelta\t\tLoopTime\t\tLoopTimeDelta\t\tvrpnPacketDelta\t\tvrpnPacketTime\t\tvrpnPacketBackup\t\tRadioRSSI\n\
&sec\t\tdegrees\t\tdegrees\t\tdegrees\t\tmeters\t\tmeters\t\tmeters\t\tdegrees\t\tdegrees\t\tseconds\t\tseconds\t\tseconds\t\tseconds\t\tseconds\t\tseconds\t\tpackets\t\tstrength\n";
const char * logHeader2 = "#Crazyflie2 Log File\n\
%Time\t\tPitch\t\tRoll\t\tYaw\t\tX\t\tY\t\tZ\t\tCamYaw\t\tCorrectedYaw\t\tLoopTimeTotal\t\tLoopTimeTotalDelta\t\tLoopTime\t\tLoopTimeDelta\t\tvrpnPacketDelta\t\tvrpnPacketTime\t\tvrpnPacketBackup\n\
&sec\t\tdegrees\t\tdegrees\t\tdegrees\t\tmeters\t\tmeters\t\tmeters\t\tdegrees\t\tdegrees\t\tseconds\t\tseconds\t\tseconds\t\tseconds\t\tseconds\t\tseconds\t\tpackets\n";
const char * logHeader3 = "#Crazyflie3 Log File\n\
%Time\t\tPitch\t\tRoll\t\tYaw\t\tX\t\tY\t\tZ\t\tCamYaw\t\tCorrectedYaw\t\tLoopTimeTotal\t\tLoopTimeTotalDelta\t\tLoopTime\t\tLoopTimeDelta\t\tvrpnPacketDelta\t\tvrpnPacketTime\t\tvrpnPacketBackup\n\
&sec\t\tdegrees\t\tdegrees\t\tdegrees\t\tmeters\t\tmeters\t\tmeters\t\tdegrees\t\tdegrees\t\tseconds\t\tseconds\t\tseconds\t\tseconds\t\tseconds\t\tseconds\t\tpackets\n";
const char * logHeader4 = "#Crazyflie4 Log File\n\
%Time\t\tPitch\t\tRoll\t\tYaw\t\tX\t\tY\t\tZ\t\tCamYaw\t\tCorrectedYaw\t\tLoopTimeTotal\t\tLoopTimeTotalDelta\t\tLoopTime\t\tLoopTimeDelta\t\tvrpnPacketDelta\t\tvrpnPacketTime\t\tvrpnPacketBackup\n\
&sec\t\tdegrees\t\tdegrees\t\tdegrees\t\tmeters\t\tmeters\t\tmeters\t\tdegrees\t\tdegrees\t\tseconds\t\tseconds\t\tseconds\t\tseconds\t\tseconds\t\tseconds\t\tpackets\n";
</pre>
</code>
</blockquote>
:4. Open External .txt file and Print Header into file
<blockquote>
<code>
<pre>
#if USE_HAND
outHand = fopen("hand.txt", "w"); //Opens text file with write permission
if(outHand == NULL)
{
printf("Could not open hand.log: errno %d\n", errno);
exit(-1);
}
fprintf(outHand, "%s\n", logHeaderHand); //Prints log header into corresponding file
#endif
if(cflieCopter1) //Checks to see if cflieCopter pointer has been initialized before opening file
{
out1 = fopen("cflie1.txt", "w");
if(out1 == NULL)
{
printf("Could not open cflie1.log: errno %d\n", errno);
exit(-1);
}
fprintf(out1, "%s\n", logHeader1);
}
if(cflieCopter2)
{
out2 = fopen("cflie2.txt", "w");
if(out2 == NULL)
{
printf("Could not open cflie2.log:errno %d\n", errno);
exit(-1);
}
fprintf(out2, "%s\n", logHeader2);
}
if(cflieCopter3)
{
out3 = fopen("cflie3.txt", "w");
if(out3 == NULL)
{
printf("Could not open cflie3.log:errno %d\n", errno);
exit(-1);
}
fprintf(out3, "%s\n", logHeader3);
}
if(cflieCopter4)
{
out4 = fopen("cflie4.txt", "w");
if(out4 == NULL)
{
printf("Could not open cflie4.log:errno %d\n", errno);
exit(-1);
}
fprintf(out4, "%s\n", logHeader4);
}
</pre>
</code>
</blockquote>
:5. Init has Completed (Start Program Loop) Prints Variable values to file...
::'''Note 1:''' This code is run at the end of the Callback for each Crazyflie initialized (Executes once per new data packet)
::'''Note 2:''' This example is using BASIC_LOGGING, and is only showing Crazyflie1's code.
<blockquote>
<code>
<pre>
fprintf(out1, "%.6f\t\t", cflieCopter1->currentTime() - initTime1 );
fprintf(out1, "%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.6f\t\t%.6f\t\t%.6f\t\t%.6f\t\t%.6f\t\t%.6f\t\t%d\t\t%d",
cflieCopter1->roll(),
cflieCopter1->pitch(),
quadYaw1,
t.pos[0],
t.pos[1],
-t.pos[2],
camYawDeg1,
correctedYaw1,
loopTimeTotal,
loopTimeTotalDelta,
loopTime1,
loopTime1Delta,
vrpnPacketDelta1,
vrpnPacketTime1,
vrpnPacketBackup1,
cflieCopter1->radioRSSI());
fprintf(out1, "\n");
</pre>
</code>
</blockquote>
:6. Close External .txt files before ending program
<blockquote>
<code>
<pre>
#if USE_LOGGING
#if USE_HAND
fclose(outHand);
#endif
#if NUM_QUADS >= 1
fclose(out1);
#endif
#if NUM_QUADS >= 2
fclose(out2);
#endif
#if NUM_QUADS >= 3
fclose(out3);
#endif
#if NUM_QUADS >= 4
fclose(out4);
#endif
#endif
</pre>
</code>
</blockquote>
==MATLAB Parser==
'''(**TODO**)'''
We use a Matlab script to parse the log files.
==New Client Log Blocks==
In the Swarm Client there is a sub-system designed for creating and maintaining Log Blocks. Once you have [[:Firmware#Log Blocks|created a new log block in the Firmware]] that you want to utilize we can do the following:
:1. Create an Enable function for the New Log Block (code in ''CCrazyflie.cpp'')
<blockquote>
<code>
<pre>
void CCrazyflie::enableMagnetometerLogging() {
m_tocLogs->registerLoggingBlock("magnetometer", 1000);
m_tocLogs->startLogging("mag.x", "magnetometer");
m_tocLogs->startLogging("mag.y", "magnetometer");
m_tocLogs->startLogging("mag.z", "magnetometer");
}
</pre>
</code>
</blockquote>
::This will then register a log block called ''magnetometer'' on the Client, which will be updated every 1000 μs. It will then update the values listed in the block (X, Y, Z of the magnetometer).
::'''Note 1:''' The ''"mag.x"'' term must match the name defined in the Firmware log block (see [[:Firmware#Log Blocks|firmware example 1]])
::'''Note 2:''' The 2nd input to the ''startLogging'' function needs to match the name of the Client Log block we registered (in this case ''"magnetometer"'')
:2. Add the ''enableLogBlock'' function we just made to the list of Log blocks we want at startup (code in ''CCrazyflie.cpp''):
<blockquote>
<code>
<pre>
bool CCrazyflie::startLogging() {
// Register the desired sensor readings
this->enableStabilizerLogging();
// this->enableGyroscopeLogging();
// this->enableAccelerometerLogging();
this->enableBatteryLogging();
this->enableMagnetometerLogging(); <-----//This is the one we just made
// this->enableAltimeterLogging();
// this->enablePIDOutputLogging();
// this->enableRadioRSSILogging();
// this->enableMotorLogging();
return true;
}
</pre>
</code>
</blockquote>
::This ''startLogging'' function runs during Crazyflie startup and will start all the log blocks listed. As you can see we have some log blocks commented out currently so that we do NOT start those blocks.
:3. Create Functions to Read the variable values during runtime (code in ''CCrazyflie.cpp''):
<blockquote>
<code>
<pre>
float CCrazyflie::magX() {
return this->sensorDoubleValue("mag.x");
}
float CCrazyflie::magY() {
return this->sensorDoubleValue("mag.y");
}
float CCrazyflie::magZ() {
return this->sensorDoubleValue("mag.z");
}
</pre>
</code>
</blockquote>
::So now we can use these sensor values, from the Firmware, in the Client code with <code>magX1 = cflieCopter1->magX()</code>. This will store the sensor value in the Client-side variable ''magX1''.
:4. (OPTIONAL) We can also create a function to stop logging an individual log block in the Client (code in ''CCrazyflie.cpp'')
<blockquote>
<code>
<pre>
void CCrazyflie::disableMagnetometerLogging() {
m_tocLogs->unregisterLoggingBlock("magnetometer");
}
</pre>
</code>
</blockquote>
::This is straightforward, it just tells the client to stop logging this block.
:5. (OPTIONAL) And we can stop ALL log blocks in the client as well (code in ''CCrazyflie.cpp''):
<blockquote>
<code>
<pre>
bool CCrazyflie::stopLogging() {
this->disableStabilizerLogging();
this->disableGyroscopeLogging();
this->disableAccelerometerLogging();
this->disableBatteryLogging();
// this->disableMagnetometerLogging();
// this->disableAltimeterLogging();
// this->disablePIDOutputLogging();
this->disableRadioRSSILogging();
this->disableMotorLogging();
return true;
}
</pre>
</code>
</blockquote>
::This will disable ALL the logging blocks included in the list.
----
<center> '''Modifications Directory''' </center>
<center> [[Crazyflie Swarm|Crazyflie Swarm Home]] | [[Controller]] | [[Logging]] | [[Keyboard Commands]] | [[USB Radio#Changing Radio Channel|Changing Radio Channel]] | [[Flight Modes]] | [[Callbacks]] | [[Adding a Crazyflie]] | [[Firmware]] </center>
a7eb1a0b9c72d960e26c4fdf86bbf714188a1acf
114
113
2016-07-20T18:05:56Z
Jnoronha
3
/* New Client Log Blocks */ changed directory to include both modifications and main pages
wikitext
text/x-wiki
The logging system is the most important analysis tool we have.
This allows us to export any variable data we want out to an external text file. This way we can use any data processor to parse the data. (Excel, MATLAB, R, etc.)
==Creating and Using the Log Files==
We first need to initialize the log files and prepare them before each test.
:1. Create empty File Pointers (code in 'eris_vrpn.cpp')
<blockquote>
<code>
<pre>
FILE * outHand = NULL;
FILE * out1 = NULL;
FILE * out2 = NULL;
FILE * out3 = NULL;
FILE * out4 = NULL;
</pre>
</code>
</blockquote>
:2. Make sure Logging is Enabled (and Basic Logging if desired)
<blockquote>
<code>
<pre>
#define USE_VRPN 1
#define USE_KEYBOARD 1
#define USE_PRINTOUT 0
#define USE_LOGGING 1 <---//Enables Full Logging
#define USE_BASIC_LOGGING 1 <---//Only logs the necessities (FULL LOGGING MUST BE ENABLED FOR THIS TO WORK)
#define USE_PR_YAW_CORRECT 0
#define USE_HAND 1
</pre>
</code>
</blockquote>
:3. Create Log File Header (# = Log File Title, % = List of Variable Names, & = List of Variable Units)
::'''Note 1:''' This example is using BASIC_LOGGING 1,
::'''Note 2:''' Variables and units are separated by a double tab '\t\t' (Does not have to be '\t\t' any delimiter works)
<blockquote>
<code>
<pre>
const char * logHeaderHand = "#Hand Log File\n\
%Time\t\tPitch\t\tRoll\t\tYaw\t\tX\t\tY\t\tZ\t\tLoopTime\t\tLoopTimeDelta\n\
&sec\t\tdegrees\t\tdegrees\t\tdegrees\t\tmeters\t\tmeters\t\tmeters\t\tseconds\t\tseconds\n";
const char * logHeader1 = "#Crazyflie1 Log File\n\
%Time\t\tPitch\t\tRoll\t\tYaw\t\tX\t\tY\t\tZ\t\tCamYaw\t\tCorrectedYaw\t\tLoopTimeTotal\t\tLoopTimeTotalDelta\t\tLoopTime\t\tLoopTimeDelta\t\tvrpnPacketDelta\t\tvrpnPacketTime\t\tvrpnPacketBackup\t\tRadioRSSI\n\
&sec\t\tdegrees\t\tdegrees\t\tdegrees\t\tmeters\t\tmeters\t\tmeters\t\tdegrees\t\tdegrees\t\tseconds\t\tseconds\t\tseconds\t\tseconds\t\tseconds\t\tseconds\t\tpackets\t\tstrength\n";
const char * logHeader2 = "#Crazyflie2 Log File\n\
%Time\t\tPitch\t\tRoll\t\tYaw\t\tX\t\tY\t\tZ\t\tCamYaw\t\tCorrectedYaw\t\tLoopTimeTotal\t\tLoopTimeTotalDelta\t\tLoopTime\t\tLoopTimeDelta\t\tvrpnPacketDelta\t\tvrpnPacketTime\t\tvrpnPacketBackup\n\
&sec\t\tdegrees\t\tdegrees\t\tdegrees\t\tmeters\t\tmeters\t\tmeters\t\tdegrees\t\tdegrees\t\tseconds\t\tseconds\t\tseconds\t\tseconds\t\tseconds\t\tseconds\t\tpackets\n";
const char * logHeader3 = "#Crazyflie3 Log File\n\
%Time\t\tPitch\t\tRoll\t\tYaw\t\tX\t\tY\t\tZ\t\tCamYaw\t\tCorrectedYaw\t\tLoopTimeTotal\t\tLoopTimeTotalDelta\t\tLoopTime\t\tLoopTimeDelta\t\tvrpnPacketDelta\t\tvrpnPacketTime\t\tvrpnPacketBackup\n\
&sec\t\tdegrees\t\tdegrees\t\tdegrees\t\tmeters\t\tmeters\t\tmeters\t\tdegrees\t\tdegrees\t\tseconds\t\tseconds\t\tseconds\t\tseconds\t\tseconds\t\tseconds\t\tpackets\n";
const char * logHeader4 = "#Crazyflie4 Log File\n\
%Time\t\tPitch\t\tRoll\t\tYaw\t\tX\t\tY\t\tZ\t\tCamYaw\t\tCorrectedYaw\t\tLoopTimeTotal\t\tLoopTimeTotalDelta\t\tLoopTime\t\tLoopTimeDelta\t\tvrpnPacketDelta\t\tvrpnPacketTime\t\tvrpnPacketBackup\n\
&sec\t\tdegrees\t\tdegrees\t\tdegrees\t\tmeters\t\tmeters\t\tmeters\t\tdegrees\t\tdegrees\t\tseconds\t\tseconds\t\tseconds\t\tseconds\t\tseconds\t\tseconds\t\tpackets\n";
</pre>
</code>
</blockquote>
:4. Open External .txt file and Print Header into file
<blockquote>
<code>
<pre>
#if USE_HAND
outHand = fopen("hand.txt", "w"); //Opens text file with write permission
if(outHand == NULL)
{
printf("Could not open hand.log: errno %d\n", errno);
exit(-1);
}
fprintf(outHand, "%s\n", logHeaderHand); //Prints log header into corresponding file
#endif
if(cflieCopter1) //Checks to see if cflieCopter pointer has been initialized before opening file
{
out1 = fopen("cflie1.txt", "w");
if(out1 == NULL)
{
printf("Could not open cflie1.log: errno %d\n", errno);
exit(-1);
}
fprintf(out1, "%s\n", logHeader1);
}
if(cflieCopter2)
{
out2 = fopen("cflie2.txt", "w");
if(out2 == NULL)
{
printf("Could not open cflie2.log:errno %d\n", errno);
exit(-1);
}
fprintf(out2, "%s\n", logHeader2);
}
if(cflieCopter3)
{
out3 = fopen("cflie3.txt", "w");
if(out3 == NULL)
{
printf("Could not open cflie3.log:errno %d\n", errno);
exit(-1);
}
fprintf(out3, "%s\n", logHeader3);
}
if(cflieCopter4)
{
out4 = fopen("cflie4.txt", "w");
if(out4 == NULL)
{
printf("Could not open cflie4.log:errno %d\n", errno);
exit(-1);
}
fprintf(out4, "%s\n", logHeader4);
}
</pre>
</code>
</blockquote>
:5. Init has Completed (Start Program Loop) Prints Variable values to file...
::'''Note 1:''' This code is run at the end of the Callback for each Crazyflie initialized (Executes once per new data packet)
::'''Note 2:''' This example is using BASIC_LOGGING, and is only showing Crazyflie1's code.
<blockquote>
<code>
<pre>
fprintf(out1, "%.6f\t\t", cflieCopter1->currentTime() - initTime1 );
fprintf(out1, "%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.6f\t\t%.6f\t\t%.6f\t\t%.6f\t\t%.6f\t\t%.6f\t\t%d\t\t%d",
cflieCopter1->roll(),
cflieCopter1->pitch(),
quadYaw1,
t.pos[0],
t.pos[1],
-t.pos[2],
camYawDeg1,
correctedYaw1,
loopTimeTotal,
loopTimeTotalDelta,
loopTime1,
loopTime1Delta,
vrpnPacketDelta1,
vrpnPacketTime1,
vrpnPacketBackup1,
cflieCopter1->radioRSSI());
fprintf(out1, "\n");
</pre>
</code>
</blockquote>
:6. Close External .txt files before ending program
<blockquote>
<code>
<pre>
#if USE_LOGGING
#if USE_HAND
fclose(outHand);
#endif
#if NUM_QUADS >= 1
fclose(out1);
#endif
#if NUM_QUADS >= 2
fclose(out2);
#endif
#if NUM_QUADS >= 3
fclose(out3);
#endif
#if NUM_QUADS >= 4
fclose(out4);
#endif
#endif
</pre>
</code>
</blockquote>
==MATLAB Parser==
'''(**TODO**)'''
We use a Matlab script to parse the log files.
==New Client Log Blocks==
In the Swarm Client there is a sub-system designed for creating and maintaining Log Blocks. Once you have [[:Firmware#Log Blocks|created a new log block in the Firmware]] that you want to utilize we can do the following:
:1. Create an Enable function for the New Log Block (code in ''CCrazyflie.cpp'')
<blockquote>
<code>
<pre>
void CCrazyflie::enableMagnetometerLogging() {
m_tocLogs->registerLoggingBlock("magnetometer", 1000);
m_tocLogs->startLogging("mag.x", "magnetometer");
m_tocLogs->startLogging("mag.y", "magnetometer");
m_tocLogs->startLogging("mag.z", "magnetometer");
}
</pre>
</code>
</blockquote>
::This will then register a log block called ''magnetometer'' on the Client, which will be updated every 1000 μs. It will then update the values listed in the block (X, Y, Z of the magnetometer).
::'''Note 1:''' The ''"mag.x"'' term must match the name defined in the Firmware log block (see [[:Firmware#Log Blocks|firmware example 1]])
::'''Note 2:''' The 2nd input to the ''startLogging'' function needs to match the name of the Client Log block we registered (in this case ''"magnetometer"'')
:2. Add the ''enableLogBlock'' function we just made to the list of Log blocks we want at startup (code in ''CCrazyflie.cpp''):
<blockquote>
<code>
<pre>
bool CCrazyflie::startLogging() {
// Register the desired sensor readings
this->enableStabilizerLogging();
// this->enableGyroscopeLogging();
// this->enableAccelerometerLogging();
this->enableBatteryLogging();
this->enableMagnetometerLogging(); <-----//This is the one we just made
// this->enableAltimeterLogging();
// this->enablePIDOutputLogging();
// this->enableRadioRSSILogging();
// this->enableMotorLogging();
return true;
}
</pre>
</code>
</blockquote>
::This ''startLogging'' function runs during Crazyflie startup and will start all the log blocks listed. As you can see we have some log blocks commented out currently so that we do NOT start those blocks.
:3. Create Functions to Read the variable values during runtime (code in ''CCrazyflie.cpp''):
<blockquote>
<code>
<pre>
float CCrazyflie::magX() {
return this->sensorDoubleValue("mag.x");
}
float CCrazyflie::magY() {
return this->sensorDoubleValue("mag.y");
}
float CCrazyflie::magZ() {
return this->sensorDoubleValue("mag.z");
}
</pre>
</code>
</blockquote>
::So now we can use these sensor values, from the Firmware, in the Client code with <code>magX1 = cflieCopter1->magX()</code>. This will store the sensor value in the Client-side variable ''magX1''.
:4. (OPTIONAL) We can also create a function to stop logging an individual log block in the Client (code in ''CCrazyflie.cpp'')
<blockquote>
<code>
<pre>
void CCrazyflie::disableMagnetometerLogging() {
m_tocLogs->unregisterLoggingBlock("magnetometer");
}
</pre>
</code>
</blockquote>
::This is straightforward, it just tells the client to stop logging this block.
:5. (OPTIONAL) And we can stop ALL log blocks in the client as well (code in ''CCrazyflie.cpp''):
<blockquote>
<code>
<pre>
bool CCrazyflie::stopLogging() {
this->disableStabilizerLogging();
this->disableGyroscopeLogging();
this->disableAccelerometerLogging();
this->disableBatteryLogging();
// this->disableMagnetometerLogging();
// this->disableAltimeterLogging();
// this->disablePIDOutputLogging();
this->disableRadioRSSILogging();
this->disableMotorLogging();
return true;
}
</pre>
</code>
</blockquote>
::This will disable ALL the logging blocks included in the list.
----
<center> '''Main Directory''' </center>
<center> [[Crazyflie Swarm|Crazyflie Swarm Home]] | [[PC Client Software]] | [[USB Radio]] | [[Firmware]] </center>
<center> '''Modifications Directory''' </center>
<center> [[Controller]] | [[Logging]] | [[Keyboard Commands]] | [[USB Radio#Changing Radio Channel|Changing Radio Channel]] | [[Flight Modes]] | [[Callbacks]] | [[Adding a Crazyflie]] | [[Firmware]] </center>
f3742349fa6ff6711419a830cfd7fe6ad08e5e8d
115
114
2016-07-20T18:13:37Z
Jnoronha
3
/* Creating and Using the Log Files */ Changed title
wikitext
text/x-wiki
The logging system is the most important analysis tool we have.
This allows us to export any variable data we want out to an external text file. This way we can use any data processor to parse the data. (Excel, MATLAB, R, etc.)
==Client-Side External Log Files==
We first need to initialize the log files and prepare them before each test.
:1. Create empty File Pointers (code in 'eris_vrpn.cpp')
<blockquote>
<code>
<pre>
FILE * outHand = NULL;
FILE * out1 = NULL;
FILE * out2 = NULL;
FILE * out3 = NULL;
FILE * out4 = NULL;
</pre>
</code>
</blockquote>
:2. Make sure Logging is Enabled (and Basic Logging if desired)
<blockquote>
<code>
<pre>
#define USE_VRPN 1
#define USE_KEYBOARD 1
#define USE_PRINTOUT 0
#define USE_LOGGING 1 <---//Enables Full Logging
#define USE_BASIC_LOGGING 1 <---//Only logs the necessities (FULL LOGGING MUST BE ENABLED FOR THIS TO WORK)
#define USE_PR_YAW_CORRECT 0
#define USE_HAND 1
</pre>
</code>
</blockquote>
:3. Create Log File Header (# = Log File Title, % = List of Variable Names, & = List of Variable Units)
::'''Note 1:''' This example is using BASIC_LOGGING 1,
::'''Note 2:''' Variables and units are separated by a double tab '\t\t' (Does not have to be '\t\t' any delimiter works)
<blockquote>
<code>
<pre>
const char * logHeaderHand = "#Hand Log File\n\
%Time\t\tPitch\t\tRoll\t\tYaw\t\tX\t\tY\t\tZ\t\tLoopTime\t\tLoopTimeDelta\n\
&sec\t\tdegrees\t\tdegrees\t\tdegrees\t\tmeters\t\tmeters\t\tmeters\t\tseconds\t\tseconds\n";
const char * logHeader1 = "#Crazyflie1 Log File\n\
%Time\t\tPitch\t\tRoll\t\tYaw\t\tX\t\tY\t\tZ\t\tCamYaw\t\tCorrectedYaw\t\tLoopTimeTotal\t\tLoopTimeTotalDelta\t\tLoopTime\t\tLoopTimeDelta\t\tvrpnPacketDelta\t\tvrpnPacketTime\t\tvrpnPacketBackup\t\tRadioRSSI\n\
&sec\t\tdegrees\t\tdegrees\t\tdegrees\t\tmeters\t\tmeters\t\tmeters\t\tdegrees\t\tdegrees\t\tseconds\t\tseconds\t\tseconds\t\tseconds\t\tseconds\t\tseconds\t\tpackets\t\tstrength\n";
const char * logHeader2 = "#Crazyflie2 Log File\n\
%Time\t\tPitch\t\tRoll\t\tYaw\t\tX\t\tY\t\tZ\t\tCamYaw\t\tCorrectedYaw\t\tLoopTimeTotal\t\tLoopTimeTotalDelta\t\tLoopTime\t\tLoopTimeDelta\t\tvrpnPacketDelta\t\tvrpnPacketTime\t\tvrpnPacketBackup\n\
&sec\t\tdegrees\t\tdegrees\t\tdegrees\t\tmeters\t\tmeters\t\tmeters\t\tdegrees\t\tdegrees\t\tseconds\t\tseconds\t\tseconds\t\tseconds\t\tseconds\t\tseconds\t\tpackets\n";
const char * logHeader3 = "#Crazyflie3 Log File\n\
%Time\t\tPitch\t\tRoll\t\tYaw\t\tX\t\tY\t\tZ\t\tCamYaw\t\tCorrectedYaw\t\tLoopTimeTotal\t\tLoopTimeTotalDelta\t\tLoopTime\t\tLoopTimeDelta\t\tvrpnPacketDelta\t\tvrpnPacketTime\t\tvrpnPacketBackup\n\
&sec\t\tdegrees\t\tdegrees\t\tdegrees\t\tmeters\t\tmeters\t\tmeters\t\tdegrees\t\tdegrees\t\tseconds\t\tseconds\t\tseconds\t\tseconds\t\tseconds\t\tseconds\t\tpackets\n";
const char * logHeader4 = "#Crazyflie4 Log File\n\
%Time\t\tPitch\t\tRoll\t\tYaw\t\tX\t\tY\t\tZ\t\tCamYaw\t\tCorrectedYaw\t\tLoopTimeTotal\t\tLoopTimeTotalDelta\t\tLoopTime\t\tLoopTimeDelta\t\tvrpnPacketDelta\t\tvrpnPacketTime\t\tvrpnPacketBackup\n\
&sec\t\tdegrees\t\tdegrees\t\tdegrees\t\tmeters\t\tmeters\t\tmeters\t\tdegrees\t\tdegrees\t\tseconds\t\tseconds\t\tseconds\t\tseconds\t\tseconds\t\tseconds\t\tpackets\n";
</pre>
</code>
</blockquote>
:4. Open External .txt file and Print Header into file
<blockquote>
<code>
<pre>
#if USE_HAND
outHand = fopen("hand.txt", "w"); //Opens text file with write permission
if(outHand == NULL)
{
printf("Could not open hand.log: errno %d\n", errno);
exit(-1);
}
fprintf(outHand, "%s\n", logHeaderHand); //Prints log header into corresponding file
#endif
if(cflieCopter1) //Checks to see if cflieCopter pointer has been initialized before opening file
{
out1 = fopen("cflie1.txt", "w");
if(out1 == NULL)
{
printf("Could not open cflie1.log: errno %d\n", errno);
exit(-1);
}
fprintf(out1, "%s\n", logHeader1);
}
if(cflieCopter2)
{
out2 = fopen("cflie2.txt", "w");
if(out2 == NULL)
{
printf("Could not open cflie2.log:errno %d\n", errno);
exit(-1);
}
fprintf(out2, "%s\n", logHeader2);
}
if(cflieCopter3)
{
out3 = fopen("cflie3.txt", "w");
if(out3 == NULL)
{
printf("Could not open cflie3.log:errno %d\n", errno);
exit(-1);
}
fprintf(out3, "%s\n", logHeader3);
}
if(cflieCopter4)
{
out4 = fopen("cflie4.txt", "w");
if(out4 == NULL)
{
printf("Could not open cflie4.log:errno %d\n", errno);
exit(-1);
}
fprintf(out4, "%s\n", logHeader4);
}
</pre>
</code>
</blockquote>
:5. Init has Completed (Start Program Loop) Prints Variable values to file...
::'''Note 1:''' This code is run at the end of the Callback for each Crazyflie initialized (Executes once per new data packet)
::'''Note 2:''' This example is using BASIC_LOGGING, and is only showing Crazyflie1's code.
<blockquote>
<code>
<pre>
fprintf(out1, "%.6f\t\t", cflieCopter1->currentTime() - initTime1 );
fprintf(out1, "%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.6f\t\t%.6f\t\t%.6f\t\t%.6f\t\t%.6f\t\t%.6f\t\t%d\t\t%d",
cflieCopter1->roll(),
cflieCopter1->pitch(),
quadYaw1,
t.pos[0],
t.pos[1],
-t.pos[2],
camYawDeg1,
correctedYaw1,
loopTimeTotal,
loopTimeTotalDelta,
loopTime1,
loopTime1Delta,
vrpnPacketDelta1,
vrpnPacketTime1,
vrpnPacketBackup1,
cflieCopter1->radioRSSI());
fprintf(out1, "\n");
</pre>
</code>
</blockquote>
:6. Close External .txt files before ending program
<blockquote>
<code>
<pre>
#if USE_LOGGING
#if USE_HAND
fclose(outHand);
#endif
#if NUM_QUADS >= 1
fclose(out1);
#endif
#if NUM_QUADS >= 2
fclose(out2);
#endif
#if NUM_QUADS >= 3
fclose(out3);
#endif
#if NUM_QUADS >= 4
fclose(out4);
#endif
#endif
</pre>
</code>
</blockquote>
==MATLAB Parser==
'''(**TODO**)'''
We use a Matlab script to parse the log files.
==New Client Log Blocks==
In the Swarm Client there is a sub-system designed for creating and maintaining Log Blocks. Once you have [[:Firmware#Log Blocks|created a new log block in the Firmware]] that you want to utilize we can do the following:
:1. Create an Enable function for the New Log Block (code in ''CCrazyflie.cpp'')
<blockquote>
<code>
<pre>
void CCrazyflie::enableMagnetometerLogging() {
m_tocLogs->registerLoggingBlock("magnetometer", 1000);
m_tocLogs->startLogging("mag.x", "magnetometer");
m_tocLogs->startLogging("mag.y", "magnetometer");
m_tocLogs->startLogging("mag.z", "magnetometer");
}
</pre>
</code>
</blockquote>
::This will then register a log block called ''magnetometer'' on the Client, which will be updated every 1000 μs. It will then update the values listed in the block (X, Y, Z of the magnetometer).
::'''Note 1:''' The ''"mag.x"'' term must match the name defined in the Firmware log block (see [[:Firmware#Log Blocks|firmware example 1]])
::'''Note 2:''' The 2nd input to the ''startLogging'' function needs to match the name of the Client Log block we registered (in this case ''"magnetometer"'')
:2. Add the ''enableLogBlock'' function we just made to the list of Log blocks we want at startup (code in ''CCrazyflie.cpp''):
<blockquote>
<code>
<pre>
bool CCrazyflie::startLogging() {
// Register the desired sensor readings
this->enableStabilizerLogging();
// this->enableGyroscopeLogging();
// this->enableAccelerometerLogging();
this->enableBatteryLogging();
this->enableMagnetometerLogging(); <-----//This is the one we just made
// this->enableAltimeterLogging();
// this->enablePIDOutputLogging();
// this->enableRadioRSSILogging();
// this->enableMotorLogging();
return true;
}
</pre>
</code>
</blockquote>
::This ''startLogging'' function runs during Crazyflie startup and will start all the log blocks listed. As you can see we have some log blocks commented out currently so that we do NOT start those blocks.
:3. Create Functions to Read the variable values during runtime (code in ''CCrazyflie.cpp''):
<blockquote>
<code>
<pre>
float CCrazyflie::magX() {
return this->sensorDoubleValue("mag.x");
}
float CCrazyflie::magY() {
return this->sensorDoubleValue("mag.y");
}
float CCrazyflie::magZ() {
return this->sensorDoubleValue("mag.z");
}
</pre>
</code>
</blockquote>
::So now we can use these sensor values, from the Firmware, in the Client code with <code>magX1 = cflieCopter1->magX()</code>. This will store the sensor value in the Client-side variable ''magX1''.
:4. (OPTIONAL) We can also create a function to stop logging an individual log block in the Client (code in ''CCrazyflie.cpp'')
<blockquote>
<code>
<pre>
void CCrazyflie::disableMagnetometerLogging() {
m_tocLogs->unregisterLoggingBlock("magnetometer");
}
</pre>
</code>
</blockquote>
::This is straightforward, it just tells the client to stop logging this block.
:5. (OPTIONAL) And we can stop ALL log blocks in the client as well (code in ''CCrazyflie.cpp''):
<blockquote>
<code>
<pre>
bool CCrazyflie::stopLogging() {
this->disableStabilizerLogging();
this->disableGyroscopeLogging();
this->disableAccelerometerLogging();
this->disableBatteryLogging();
// this->disableMagnetometerLogging();
// this->disableAltimeterLogging();
// this->disablePIDOutputLogging();
this->disableRadioRSSILogging();
this->disableMotorLogging();
return true;
}
</pre>
</code>
</blockquote>
::This will disable ALL the logging blocks included in the list.
----
<center> '''Main Directory''' </center>
<center> [[Crazyflie Swarm|Crazyflie Swarm Home]] | [[PC Client Software]] | [[USB Radio]] | [[Firmware]] </center>
<center> '''Modifications Directory''' </center>
<center> [[Controller]] | [[Logging]] | [[Keyboard Commands]] | [[USB Radio#Changing Radio Channel|Changing Radio Channel]] | [[Flight Modes]] | [[Callbacks]] | [[Adding a Crazyflie]] | [[Firmware]] </center>
78b8807e20310b15ceaa7df25890966d6e95d9f9
117
115
2016-07-20T18:23:24Z
Jnoronha
3
/* New Client Log Blocks */ Added FAQ to directory
wikitext
text/x-wiki
The logging system is the most important analysis tool we have.
This allows us to export any variable data we want out to an external text file. This way we can use any data processor to parse the data. (Excel, MATLAB, R, etc.)
==Client-Side External Log Files==
We first need to initialize the log files and prepare them before each test.
:1. Create empty File Pointers (code in 'eris_vrpn.cpp')
<blockquote>
<code>
<pre>
FILE * outHand = NULL;
FILE * out1 = NULL;
FILE * out2 = NULL;
FILE * out3 = NULL;
FILE * out4 = NULL;
</pre>
</code>
</blockquote>
:2. Make sure Logging is Enabled (and Basic Logging if desired)
<blockquote>
<code>
<pre>
#define USE_VRPN 1
#define USE_KEYBOARD 1
#define USE_PRINTOUT 0
#define USE_LOGGING 1 <---//Enables Full Logging
#define USE_BASIC_LOGGING 1 <---//Only logs the necessities (FULL LOGGING MUST BE ENABLED FOR THIS TO WORK)
#define USE_PR_YAW_CORRECT 0
#define USE_HAND 1
</pre>
</code>
</blockquote>
:3. Create Log File Header (# = Log File Title, % = List of Variable Names, & = List of Variable Units)
::'''Note 1:''' This example is using BASIC_LOGGING 1,
::'''Note 2:''' Variables and units are separated by a double tab '\t\t' (Does not have to be '\t\t' any delimiter works)
<blockquote>
<code>
<pre>
const char * logHeaderHand = "#Hand Log File\n\
%Time\t\tPitch\t\tRoll\t\tYaw\t\tX\t\tY\t\tZ\t\tLoopTime\t\tLoopTimeDelta\n\
&sec\t\tdegrees\t\tdegrees\t\tdegrees\t\tmeters\t\tmeters\t\tmeters\t\tseconds\t\tseconds\n";
const char * logHeader1 = "#Crazyflie1 Log File\n\
%Time\t\tPitch\t\tRoll\t\tYaw\t\tX\t\tY\t\tZ\t\tCamYaw\t\tCorrectedYaw\t\tLoopTimeTotal\t\tLoopTimeTotalDelta\t\tLoopTime\t\tLoopTimeDelta\t\tvrpnPacketDelta\t\tvrpnPacketTime\t\tvrpnPacketBackup\t\tRadioRSSI\n\
&sec\t\tdegrees\t\tdegrees\t\tdegrees\t\tmeters\t\tmeters\t\tmeters\t\tdegrees\t\tdegrees\t\tseconds\t\tseconds\t\tseconds\t\tseconds\t\tseconds\t\tseconds\t\tpackets\t\tstrength\n";
const char * logHeader2 = "#Crazyflie2 Log File\n\
%Time\t\tPitch\t\tRoll\t\tYaw\t\tX\t\tY\t\tZ\t\tCamYaw\t\tCorrectedYaw\t\tLoopTimeTotal\t\tLoopTimeTotalDelta\t\tLoopTime\t\tLoopTimeDelta\t\tvrpnPacketDelta\t\tvrpnPacketTime\t\tvrpnPacketBackup\n\
&sec\t\tdegrees\t\tdegrees\t\tdegrees\t\tmeters\t\tmeters\t\tmeters\t\tdegrees\t\tdegrees\t\tseconds\t\tseconds\t\tseconds\t\tseconds\t\tseconds\t\tseconds\t\tpackets\n";
const char * logHeader3 = "#Crazyflie3 Log File\n\
%Time\t\tPitch\t\tRoll\t\tYaw\t\tX\t\tY\t\tZ\t\tCamYaw\t\tCorrectedYaw\t\tLoopTimeTotal\t\tLoopTimeTotalDelta\t\tLoopTime\t\tLoopTimeDelta\t\tvrpnPacketDelta\t\tvrpnPacketTime\t\tvrpnPacketBackup\n\
&sec\t\tdegrees\t\tdegrees\t\tdegrees\t\tmeters\t\tmeters\t\tmeters\t\tdegrees\t\tdegrees\t\tseconds\t\tseconds\t\tseconds\t\tseconds\t\tseconds\t\tseconds\t\tpackets\n";
const char * logHeader4 = "#Crazyflie4 Log File\n\
%Time\t\tPitch\t\tRoll\t\tYaw\t\tX\t\tY\t\tZ\t\tCamYaw\t\tCorrectedYaw\t\tLoopTimeTotal\t\tLoopTimeTotalDelta\t\tLoopTime\t\tLoopTimeDelta\t\tvrpnPacketDelta\t\tvrpnPacketTime\t\tvrpnPacketBackup\n\
&sec\t\tdegrees\t\tdegrees\t\tdegrees\t\tmeters\t\tmeters\t\tmeters\t\tdegrees\t\tdegrees\t\tseconds\t\tseconds\t\tseconds\t\tseconds\t\tseconds\t\tseconds\t\tpackets\n";
</pre>
</code>
</blockquote>
:4. Open External .txt file and Print Header into file
<blockquote>
<code>
<pre>
#if USE_HAND
outHand = fopen("hand.txt", "w"); //Opens text file with write permission
if(outHand == NULL)
{
printf("Could not open hand.log: errno %d\n", errno);
exit(-1);
}
fprintf(outHand, "%s\n", logHeaderHand); //Prints log header into corresponding file
#endif
if(cflieCopter1) //Checks to see if cflieCopter pointer has been initialized before opening file
{
out1 = fopen("cflie1.txt", "w");
if(out1 == NULL)
{
printf("Could not open cflie1.log: errno %d\n", errno);
exit(-1);
}
fprintf(out1, "%s\n", logHeader1);
}
if(cflieCopter2)
{
out2 = fopen("cflie2.txt", "w");
if(out2 == NULL)
{
printf("Could not open cflie2.log:errno %d\n", errno);
exit(-1);
}
fprintf(out2, "%s\n", logHeader2);
}
if(cflieCopter3)
{
out3 = fopen("cflie3.txt", "w");
if(out3 == NULL)
{
printf("Could not open cflie3.log:errno %d\n", errno);
exit(-1);
}
fprintf(out3, "%s\n", logHeader3);
}
if(cflieCopter4)
{
out4 = fopen("cflie4.txt", "w");
if(out4 == NULL)
{
printf("Could not open cflie4.log:errno %d\n", errno);
exit(-1);
}
fprintf(out4, "%s\n", logHeader4);
}
</pre>
</code>
</blockquote>
:5. Init has Completed (Start Program Loop) Prints Variable values to file...
::'''Note 1:''' This code is run at the end of the Callback for each Crazyflie initialized (Executes once per new data packet)
::'''Note 2:''' This example is using BASIC_LOGGING, and is only showing Crazyflie1's code.
<blockquote>
<code>
<pre>
fprintf(out1, "%.6f\t\t", cflieCopter1->currentTime() - initTime1 );
fprintf(out1, "%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.6f\t\t%.6f\t\t%.6f\t\t%.6f\t\t%.6f\t\t%.6f\t\t%d\t\t%d",
cflieCopter1->roll(),
cflieCopter1->pitch(),
quadYaw1,
t.pos[0],
t.pos[1],
-t.pos[2],
camYawDeg1,
correctedYaw1,
loopTimeTotal,
loopTimeTotalDelta,
loopTime1,
loopTime1Delta,
vrpnPacketDelta1,
vrpnPacketTime1,
vrpnPacketBackup1,
cflieCopter1->radioRSSI());
fprintf(out1, "\n");
</pre>
</code>
</blockquote>
:6. Close External .txt files before ending program
<blockquote>
<code>
<pre>
#if USE_LOGGING
#if USE_HAND
fclose(outHand);
#endif
#if NUM_QUADS >= 1
fclose(out1);
#endif
#if NUM_QUADS >= 2
fclose(out2);
#endif
#if NUM_QUADS >= 3
fclose(out3);
#endif
#if NUM_QUADS >= 4
fclose(out4);
#endif
#endif
</pre>
</code>
</blockquote>
==MATLAB Parser==
'''(**TODO**)'''
We use a Matlab script to parse the log files.
==New Client Log Blocks==
In the Swarm Client there is a sub-system designed for creating and maintaining Log Blocks. Once you have [[:Firmware#Log Blocks|created a new log block in the Firmware]] that you want to utilize we can do the following:
:1. Create an Enable function for the New Log Block (code in ''CCrazyflie.cpp'')
<blockquote>
<code>
<pre>
void CCrazyflie::enableMagnetometerLogging() {
m_tocLogs->registerLoggingBlock("magnetometer", 1000);
m_tocLogs->startLogging("mag.x", "magnetometer");
m_tocLogs->startLogging("mag.y", "magnetometer");
m_tocLogs->startLogging("mag.z", "magnetometer");
}
</pre>
</code>
</blockquote>
::This will then register a log block called ''magnetometer'' on the Client, which will be updated every 1000 μs. It will then update the values listed in the block (X, Y, Z of the magnetometer).
::'''Note 1:''' The ''"mag.x"'' term must match the name defined in the Firmware log block (see [[:Firmware#Log Blocks|firmware example 1]])
::'''Note 2:''' The 2nd input to the ''startLogging'' function needs to match the name of the Client Log block we registered (in this case ''"magnetometer"'')
:2. Add the ''enableLogBlock'' function we just made to the list of Log blocks we want at startup (code in ''CCrazyflie.cpp''):
<blockquote>
<code>
<pre>
bool CCrazyflie::startLogging() {
// Register the desired sensor readings
this->enableStabilizerLogging();
// this->enableGyroscopeLogging();
// this->enableAccelerometerLogging();
this->enableBatteryLogging();
this->enableMagnetometerLogging(); <-----//This is the one we just made
// this->enableAltimeterLogging();
// this->enablePIDOutputLogging();
// this->enableRadioRSSILogging();
// this->enableMotorLogging();
return true;
}
</pre>
</code>
</blockquote>
::This ''startLogging'' function runs during Crazyflie startup and will start all the log blocks listed. As you can see we have some log blocks commented out currently so that we do NOT start those blocks.
:3. Create Functions to Read the variable values during runtime (code in ''CCrazyflie.cpp''):
<blockquote>
<code>
<pre>
float CCrazyflie::magX() {
return this->sensorDoubleValue("mag.x");
}
float CCrazyflie::magY() {
return this->sensorDoubleValue("mag.y");
}
float CCrazyflie::magZ() {
return this->sensorDoubleValue("mag.z");
}
</pre>
</code>
</blockquote>
::So now we can use these sensor values, from the Firmware, in the Client code with <code>magX1 = cflieCopter1->magX()</code>. This will store the sensor value in the Client-side variable ''magX1''.
:4. (OPTIONAL) We can also create a function to stop logging an individual log block in the Client (code in ''CCrazyflie.cpp'')
<blockquote>
<code>
<pre>
void CCrazyflie::disableMagnetometerLogging() {
m_tocLogs->unregisterLoggingBlock("magnetometer");
}
</pre>
</code>
</blockquote>
::This is straightforward, it just tells the client to stop logging this block.
:5. (OPTIONAL) And we can stop ALL log blocks in the client as well (code in ''CCrazyflie.cpp''):
<blockquote>
<code>
<pre>
bool CCrazyflie::stopLogging() {
this->disableStabilizerLogging();
this->disableGyroscopeLogging();
this->disableAccelerometerLogging();
this->disableBatteryLogging();
// this->disableMagnetometerLogging();
// this->disableAltimeterLogging();
// this->disablePIDOutputLogging();
this->disableRadioRSSILogging();
this->disableMotorLogging();
return true;
}
</pre>
</code>
</blockquote>
::This will disable ALL the logging blocks included in the list.
----
<center> '''Main Directory''' </center>
<center> [[Crazyflie Swarm|Crazyflie Swarm Home]] | [[PC Client Software]] | [[USB Radio]] | [[Firmware]] | [[FAQ]] </center>
<center> '''Modifications Directory''' </center>
<center> [[Controller]] | [[Logging]] | [[Keyboard Commands]] | [[USB Radio#Changing Radio Channel|Changing Radio Channel]] | [[Flight Modes]] | [[Callbacks]] | [[Adding a Crazyflie]] | [[Firmware]] </center>
e84925610055eec1271eb4b67a199d9ea45c58d1
Firmware
0
26
102
58
2016-07-20T16:04:35Z
Jnoronha
3
Added Firmware Log block examples
wikitext
text/x-wiki
Not much work has been done in the Firmware yet. (as of 7/20/16) The few things we have been able to successfully modify are:
#Creating New Log Blocks
#Modifying the Default Yaw Mode
#Adding and Modifying Parameter Values
==Log Blocks==
In the Crazyflie Firmware there is a generalized logging framework that allows us to make any group of variables into a log block. It makes things very easy to log. Here are a few examples:
:1. Magnometer Log Block (code found in ''Firmware > modules > src > stabilizer.c'')
<blockquote>
<code>
<pre>
LOG_GROUP_START(mag)
LOG_ADD(LOG_FLOAT, x, &mag.x)
LOG_ADD(LOG_FLOAT, y, &mag.y)
LOG_ADD(LOG_FLOAT, z, &mag.z)
LOG_GROUP_STOP(mag)
</pre>
</code>
</blockquote>
:So with this code we have created a log block called 'mag' and it contains the X, Y, and Z measurements from the magnetometer sensor.
:2. Accelerometer Log Block (code found in ''Firmware > modules > src > stabilizer.c'')
<blockquote>
<code>
<pre>
LOG_GROUP_START(acc)
LOG_ADD(LOG_FLOAT, x, &acc.x)
LOG_ADD(LOG_FLOAT, y, &acc.y)
LOG_ADD(LOG_FLOAT, z, &acc.z)
LOG_ADD(LOG_FLOAT, zw, &accWZ)
LOG_ADD(LOG_FLOAT, mag2, &accMAG)
LOG_GROUP_STOP(acc)
</pre>
</code>
</blockquote>
:So just like in the magnetometer block, here we have created a log group called 'acc' and inside this group we are logging the variables for the accelerometer's X, Y, and Z values as well as 2 other gravity based variables used for thrust compensation.
===Using New Log Blocks in Swarm Client===
----
<center> [[Crazyflie Swarm]] | [[PC Client Software]] | [[USB Radio]] | [[Firmware]] </center>
a617ebab2c936ac90612d8d5a5820ceb715e0132
104
102
2016-07-20T16:45:45Z
Jnoronha
3
/* Log Blocks */ linked to using new log blocks in Client
wikitext
text/x-wiki
Not much work has been done in the Firmware yet. (as of 7/20/16) The few things we have been able to successfully modify are:
#Creating New Log Blocks
#Modifying the Default Yaw Mode
#Adding and Modifying Parameter Values
==Log Blocks==
In the Crazyflie Firmware there is a generalized logging framework that allows us to make any group of variables into a log block. It makes things very easy to log. Here are a few examples:
:1. Magnometer Log Block (code found in ''Firmware > modules > src > stabilizer.c'')
<blockquote>
<code>
<pre>
LOG_GROUP_START(mag)
LOG_ADD(LOG_FLOAT, x, &mag.x)
LOG_ADD(LOG_FLOAT, y, &mag.y)
LOG_ADD(LOG_FLOAT, z, &mag.z)
LOG_GROUP_STOP(mag)
</pre>
</code>
</blockquote>
:So with this code we have created a log block called 'mag' and it contains the X, Y, and Z measurements from the magnetometer sensor.
:2. Accelerometer Log Block (code found in ''Firmware > modules > src > stabilizer.c'')
<blockquote>
<code>
<pre>
LOG_GROUP_START(acc)
LOG_ADD(LOG_FLOAT, x, &acc.x)
LOG_ADD(LOG_FLOAT, y, &acc.y)
LOG_ADD(LOG_FLOAT, z, &acc.z)
LOG_ADD(LOG_FLOAT, zw, &accWZ)
LOG_ADD(LOG_FLOAT, mag2, &accMAG)
LOG_GROUP_STOP(acc)
</pre>
</code>
</blockquote>
:So just like in the magnetometer block, here we have created a log group called 'acc' and inside this group we are logging the variables for the accelerometer's X, Y, and Z values as well as 2 other gravity based variables used for thrust compensation.
===Using New Log Blocks in Swarm Client===
Now that we have these new log blocks, we can [[:Logging#Starting New Log Blocks|use log blocks in the Client]]
----
<center> [[Crazyflie Swarm]] | [[PC Client Software]] | [[USB Radio]] | [[Firmware]] </center>
d7f8949456c1aabce7db5a489d19be0b6bc94af3
106
104
2016-07-20T16:48:07Z
Jnoronha
3
/* Using New Log Blocks in Swarm Client */ fixed link to client log blocks
wikitext
text/x-wiki
Not much work has been done in the Firmware yet. (as of 7/20/16) The few things we have been able to successfully modify are:
#Creating New Log Blocks
#Modifying the Default Yaw Mode
#Adding and Modifying Parameter Values
==Log Blocks==
In the Crazyflie Firmware there is a generalized logging framework that allows us to make any group of variables into a log block. It makes things very easy to log. Here are a few examples:
:1. Magnometer Log Block (code found in ''Firmware > modules > src > stabilizer.c'')
<blockquote>
<code>
<pre>
LOG_GROUP_START(mag)
LOG_ADD(LOG_FLOAT, x, &mag.x)
LOG_ADD(LOG_FLOAT, y, &mag.y)
LOG_ADD(LOG_FLOAT, z, &mag.z)
LOG_GROUP_STOP(mag)
</pre>
</code>
</blockquote>
:So with this code we have created a log block called 'mag' and it contains the X, Y, and Z measurements from the magnetometer sensor.
:2. Accelerometer Log Block (code found in ''Firmware > modules > src > stabilizer.c'')
<blockquote>
<code>
<pre>
LOG_GROUP_START(acc)
LOG_ADD(LOG_FLOAT, x, &acc.x)
LOG_ADD(LOG_FLOAT, y, &acc.y)
LOG_ADD(LOG_FLOAT, z, &acc.z)
LOG_ADD(LOG_FLOAT, zw, &accWZ)
LOG_ADD(LOG_FLOAT, mag2, &accMAG)
LOG_GROUP_STOP(acc)
</pre>
</code>
</blockquote>
:So just like in the magnetometer block, here we have created a log group called 'acc' and inside this group we are logging the variables for the accelerometer's X, Y, and Z values as well as 2 other gravity based variables used for thrust compensation.
===Using New Log Blocks in Swarm Client===
Now that we have these new log blocks, we can [[:Logging#New Client Log Blocks|use log blocks in the Client]]
----
<center> [[Crazyflie Swarm]] | [[PC Client Software]] | [[USB Radio]] | [[Firmware]] </center>
69be7e1c0a17bcc21ae22fb768da2134e60ca2fb
107
106
2016-07-20T16:49:18Z
Jnoronha
3
/* Using New Log Blocks in Swarm Client */ added in firmware detail
wikitext
text/x-wiki
Not much work has been done in the Firmware yet. (as of 7/20/16) The few things we have been able to successfully modify are:
#Creating New Log Blocks
#Modifying the Default Yaw Mode
#Adding and Modifying Parameter Values
==Log Blocks==
In the Crazyflie Firmware there is a generalized logging framework that allows us to make any group of variables into a log block. It makes things very easy to log. Here are a few examples:
:1. Magnometer Log Block (code found in ''Firmware > modules > src > stabilizer.c'')
<blockquote>
<code>
<pre>
LOG_GROUP_START(mag)
LOG_ADD(LOG_FLOAT, x, &mag.x)
LOG_ADD(LOG_FLOAT, y, &mag.y)
LOG_ADD(LOG_FLOAT, z, &mag.z)
LOG_GROUP_STOP(mag)
</pre>
</code>
</blockquote>
:So with this code we have created a log block called 'mag' and it contains the X, Y, and Z measurements from the magnetometer sensor.
:2. Accelerometer Log Block (code found in ''Firmware > modules > src > stabilizer.c'')
<blockquote>
<code>
<pre>
LOG_GROUP_START(acc)
LOG_ADD(LOG_FLOAT, x, &acc.x)
LOG_ADD(LOG_FLOAT, y, &acc.y)
LOG_ADD(LOG_FLOAT, z, &acc.z)
LOG_ADD(LOG_FLOAT, zw, &accWZ)
LOG_ADD(LOG_FLOAT, mag2, &accMAG)
LOG_GROUP_STOP(acc)
</pre>
</code>
</blockquote>
:So just like in the magnetometer block, here we have created a log group called 'acc' and inside this group we are logging the variables for the accelerometer's X, Y, and Z values as well as 2 other gravity based variables used for thrust compensation.
===Using New Log Blocks in Swarm Client===
Now that we have these new log blocks in the Firmware, we can [[:Logging#New Client Log Blocks|use log blocks in the Client]]
----
<center> [[Crazyflie Swarm]] | [[PC Client Software]] | [[USB Radio]] | [[Firmware]] </center>
2840a8d63acbd8c6532ba4db045c933e92d03aa8
108
107
2016-07-20T17:05:49Z
Jnoronha
3
/* Log Blocks */
wikitext
text/x-wiki
Not much work has been done in the Firmware yet. (as of 7/20/16) The few things we have been able to successfully modify are:
#Creating New Log Blocks
#Modifying the Default Yaw Mode
#Adding and Modifying Parameter Values
==Log Blocks==
In the Crazyflie Firmware there is a generalized logging framework that allows us to make any group of variables into a log block. It makes things very easy to log. Here are a few examples:
:Ex. 1. Magnometer Log Block (code found in ''Firmware > modules > src > stabilizer.c'')
<blockquote>
<code>
<pre>
LOG_GROUP_START(mag)
LOG_ADD(LOG_FLOAT, x, &mag.x)
LOG_ADD(LOG_FLOAT, y, &mag.y)
LOG_ADD(LOG_FLOAT, z, &mag.z)
LOG_GROUP_STOP(mag)
</pre>
</code>
</blockquote>
::So with this code we have created a log block called 'mag' and it contains the X, Y, and Z measurements from the magnetometer sensor.
:Ex. 2. Accelerometer Log Block (code found in ''Firmware > modules > src > stabilizer.c'')
<blockquote>
<code>
<pre>
LOG_GROUP_START(acc)
LOG_ADD(LOG_FLOAT, x, &acc.x)
LOG_ADD(LOG_FLOAT, y, &acc.y)
LOG_ADD(LOG_FLOAT, z, &acc.z)
LOG_ADD(LOG_FLOAT, zw, &accWZ)
LOG_ADD(LOG_FLOAT, mag2, &accMAG)
LOG_GROUP_STOP(acc)
</pre>
</code>
</blockquote>
::Just like in the magnetometer block, here we have created a log group called 'acc' and inside this group we are logging the variables for the accelerometer's X, Y, and Z values as well as 2 other gravity based variables used for thrust compensation.
===Using New Log Blocks in Swarm Client===
Now that we have these new log blocks in the Firmware, we can [[:Logging#New Client Log Blocks|use log blocks in the Client]]
----
<center> [[Crazyflie Swarm]] | [[PC Client Software]] | [[USB Radio]] | [[Firmware]] </center>
50cfa13915f3ec51b2274ac5a9603af8e2a343c0
116
108
2016-07-20T18:14:51Z
Jnoronha
3
/* Log Blocks */ changed title
wikitext
text/x-wiki
Not much work has been done in the Firmware yet. (as of 7/20/16) The few things we have been able to successfully modify are:
#Creating New Log Blocks
#Modifying the Default Yaw Mode
#Adding and Modifying Parameter Values
==New Firmware Log Blocks==
In the Crazyflie Firmware there is a generalized logging framework that allows us to make any group of variables into a log block. It makes things very easy to log. Here are a few examples:
:Ex. 1. Magnometer Log Block (code found in ''Firmware > modules > src > stabilizer.c'')
<blockquote>
<code>
<pre>
LOG_GROUP_START(mag)
LOG_ADD(LOG_FLOAT, x, &mag.x)
LOG_ADD(LOG_FLOAT, y, &mag.y)
LOG_ADD(LOG_FLOAT, z, &mag.z)
LOG_GROUP_STOP(mag)
</pre>
</code>
</blockquote>
::So with this code we have created a log block called 'mag' and it contains the X, Y, and Z measurements from the magnetometer sensor.
:Ex. 2. Accelerometer Log Block (code found in ''Firmware > modules > src > stabilizer.c'')
<blockquote>
<code>
<pre>
LOG_GROUP_START(acc)
LOG_ADD(LOG_FLOAT, x, &acc.x)
LOG_ADD(LOG_FLOAT, y, &acc.y)
LOG_ADD(LOG_FLOAT, z, &acc.z)
LOG_ADD(LOG_FLOAT, zw, &accWZ)
LOG_ADD(LOG_FLOAT, mag2, &accMAG)
LOG_GROUP_STOP(acc)
</pre>
</code>
</blockquote>
::Just like in the magnetometer block, here we have created a log group called 'acc' and inside this group we are logging the variables for the accelerometer's X, Y, and Z values as well as 2 other gravity based variables used for thrust compensation.
===Using New Log Blocks in Swarm Client===
Now that we have these new log blocks in the Firmware, we can [[:Logging#New Client Log Blocks|use log blocks in the Client]]
----
<center> [[Crazyflie Swarm]] | [[PC Client Software]] | [[USB Radio]] | [[Firmware]] </center>
2c8d0cbc2b4ec90d9df69b013a192642b0946fc4
121
116
2016-07-20T18:58:57Z
Jnoronha
3
/* Using New Log Blocks in Swarm Client */ modified directory
wikitext
text/x-wiki
Not much work has been done in the Firmware yet. (as of 7/20/16) The few things we have been able to successfully modify are:
#Creating New Log Blocks
#Modifying the Default Yaw Mode
#Adding and Modifying Parameter Values
==New Firmware Log Blocks==
In the Crazyflie Firmware there is a generalized logging framework that allows us to make any group of variables into a log block. It makes things very easy to log. Here are a few examples:
:Ex. 1. Magnometer Log Block (code found in ''Firmware > modules > src > stabilizer.c'')
<blockquote>
<code>
<pre>
LOG_GROUP_START(mag)
LOG_ADD(LOG_FLOAT, x, &mag.x)
LOG_ADD(LOG_FLOAT, y, &mag.y)
LOG_ADD(LOG_FLOAT, z, &mag.z)
LOG_GROUP_STOP(mag)
</pre>
</code>
</blockquote>
::So with this code we have created a log block called 'mag' and it contains the X, Y, and Z measurements from the magnetometer sensor.
:Ex. 2. Accelerometer Log Block (code found in ''Firmware > modules > src > stabilizer.c'')
<blockquote>
<code>
<pre>
LOG_GROUP_START(acc)
LOG_ADD(LOG_FLOAT, x, &acc.x)
LOG_ADD(LOG_FLOAT, y, &acc.y)
LOG_ADD(LOG_FLOAT, z, &acc.z)
LOG_ADD(LOG_FLOAT, zw, &accWZ)
LOG_ADD(LOG_FLOAT, mag2, &accMAG)
LOG_GROUP_STOP(acc)
</pre>
</code>
</blockquote>
::Just like in the magnetometer block, here we have created a log group called 'acc' and inside this group we are logging the variables for the accelerometer's X, Y, and Z values as well as 2 other gravity based variables used for thrust compensation.
===Using New Log Blocks in Swarm Client===
Now that we have these new log blocks in the Firmware, we can [[:Logging#New Client Log Blocks|use log blocks in the Client]]
----
<center> '''Main Directory''' </center>
<center> [[Crazyflie Swarm|Crazyflie Swarm Home]] | [[PC Client Software]] | [[USB Radio]] | [[Firmware]] | [[FAQ]] </center>
<center> '''Modifications Directory''' </center>
<center> [[Controller]] | [[Logging]] | [[Keyboard Commands]] | [[USB Radio#Changing Radio Channel|Changing Radio Channel]] | [[Flight Modes]] | [[Callbacks]] | [[Adding a Crazyflie]] | [[Firmware]] </center>
4c6303e2774532187b647a83bdd64fb1aa04f7e8
123
121
2016-07-21T17:50:51Z
Jnoronha
3
finished yaw modification section (still missing final FIRMWARE yaw change code)
wikitext
text/x-wiki
Not much work has been done in the Firmware yet (as of 7/20/16). The few things we have been able to successfully modify are:
#Creating New Log Blocks
#Modifying the Default Yaw Mode
#Adding and Modifying Parameter Values
==New Firmware Log Blocks==
In the Crazyflie Firmware there is a generalized logging framework that allows us to make any group of variables into a log block. It makes things very easy to log. Here are a few examples:
:Ex. 1. Magnometer Log Block (code found in ''Firmware > modules > src > stabilizer.c'')
<blockquote>
<code>
<pre>
LOG_GROUP_START(mag)
LOG_ADD(LOG_FLOAT, x, &mag.x)
LOG_ADD(LOG_FLOAT, y, &mag.y)
LOG_ADD(LOG_FLOAT, z, &mag.z)
LOG_GROUP_STOP(mag)
</pre>
</code>
</blockquote>
::So with this code we have created a log block called 'mag' and it contains the X, Y, and Z measurements from the magnetometer sensor.
:Ex. 2. Accelerometer Log Block (code found in ''Firmware > modules > src > stabilizer.c'')
<blockquote>
<code>
<pre>
LOG_GROUP_START(acc)
LOG_ADD(LOG_FLOAT, x, &acc.x)
LOG_ADD(LOG_FLOAT, y, &acc.y)
LOG_ADD(LOG_FLOAT, z, &acc.z)
LOG_ADD(LOG_FLOAT, zw, &accWZ)
LOG_ADD(LOG_FLOAT, mag2, &accMAG)
LOG_GROUP_STOP(acc)
</pre>
</code>
</blockquote>
::Just like in the magnetometer block, here we have created a log group called 'acc' and inside this group we are logging the variables for the accelerometer's X, Y, and Z values as well as 2 other gravity based variables used for thrust compensation.
===Using New Log Blocks in Swarm Client===
Now that we have these new log blocks in the Firmware, we can [[:Logging#New Client Log Blocks|use log blocks in the Client]]
==Modify the Default Yaw Mode==
There are 3 types of Yaw Modes available in the Firmware (as of 7/21/16), as shown (code in ''Firmware > modules > interface > commander.h'')
<blockquote>
<code>
<pre>
typedef enum
{
CAREFREE = 0, // Yaw is locked to world coordinates thus heading stays the same when yaw rotates
PLUSMODE = 1, // Plus-mode. Motor M1 is defined as front
XMODE = 2, // X-mode. M1 & M4 is defined as front
} YawModeType;
</pre>
</code>
</blockquote>
:'''Note:''' The default mode for the Crazyflie 2.0 is ''XMODE''. The ''PLUSMODE'' is default for the Crazyflie 1.0, but can still be used on the Crazyflie 2.0 if desired.
===Carefree Mode===
''CAREFREE'' mode is what our Crazyflie 2.0's are using, this mode applies a transformation to the Pitch and Roll setpoints depending on the angle of Yaw. We used to perform this calculation on the Client like this (code in ''eris_vrpn.cpp''):
<blockquote>
<code>
<pre>
#if USE_PR_YAW_CORRECT
//CORRECTS PITCH AND ROLL PID ERRORS TO ACCOUNT FOR QUADS CURRENT YAW DIRECTION (_/57.2958 converts DEG to RADIANS)
xError2 = cos(correctedYaw2 / 57.2958)*(xPositionDesired2 - xPosition2) - sin(correctedYaw2 / 57.2958)*(yPositionDesired2 - yPosition2);
yError2 = sin(correctedYaw2 / 57.2958)*(xPositionDesired2 - xPosition2) + cos(correctedYaw2 / 57.2958)*(yPositionDesired2 - yPosition2);
#else
xError2 = xPositionDesired2 - xPosition2;
yError2 = yPositionDesired2 - yPosition2;
#endif
controllerSetXYError(&pidCtrl2, xError2, yError2);
</pre>
</code>
</blockquote>
This is no longer necessary on the Client because this is the exact same calculation ''CAREFREE'' mode performs on the Firmware. So this reduces the computation done on the Client in each Crazyflie Callback.
====Changing Yaw Mode in Firmware====
To change the Yaw Mode to ''CAREFREE'' mode we had to make the modification shown (code in ''Firmware > modules > src > commander.c''):
<blockquote>
<code>
<pre>
***INSERT CODE CHANGE***
</pre>
</code>
</blockquote>
----
<center> '''Main Directory''' </center>
<center> [[Crazyflie Swarm|Crazyflie Swarm Home]] | [[PC Client Software]] | [[USB Radio]] | [[Firmware]] | [[FAQ]] </center>
<center> '''Modifications Directory''' </center>
<center> [[Controller]] | [[Logging]] | [[Keyboard Commands]] | [[USB Radio#Changing Radio Channel|Changing Radio Channel]] | [[Flight Modes]] | [[Callbacks]] | [[Adding a Crazyflie]] | [[Firmware]] </center>
969c0c11b2bc09f87f24fbddbb3aa22b9fdb0acf
124
123
2016-07-21T18:11:54Z
Jnoronha
3
Finished Params section
wikitext
text/x-wiki
Not much work has been done in the Firmware yet (as of 7/20/16). The few things we have been able to successfully modify are:
#Creating New Log Blocks
#Modifying the Default Yaw Mode
#Adding and Modifying Parameter Values
==New Firmware Log Blocks==
In the Crazyflie Firmware there is a generalized logging framework that allows us to make any group of variables into a log block. It makes things very easy to log. Here are a few examples:
:'''IMPORTANT:''' If you want to create new Log groups in a file, make sure you include <code>#include "log.h"</code> at the top of the file.
:Ex. 1. Magnometer Log Block (code found in ''Firmware > modules > src > stabilizer.c'')
<blockquote>
<code>
<pre>
LOG_GROUP_START(mag)
LOG_ADD(LOG_FLOAT, x, &mag.x)
LOG_ADD(LOG_FLOAT, y, &mag.y)
LOG_ADD(LOG_FLOAT, z, &mag.z)
LOG_GROUP_STOP(mag)
</pre>
</code>
</blockquote>
::So with this code we have created a log block called 'mag' and it contains the X, Y, and Z measurements from the magnetometer sensor.
:Ex. 2. Accelerometer Log Block (code found in ''Firmware > modules > src > stabilizer.c'')
<blockquote>
<code>
<pre>
LOG_GROUP_START(acc)
LOG_ADD(LOG_FLOAT, x, &acc.x)
LOG_ADD(LOG_FLOAT, y, &acc.y)
LOG_ADD(LOG_FLOAT, z, &acc.z)
LOG_ADD(LOG_FLOAT, zw, &accWZ)
LOG_ADD(LOG_FLOAT, mag2, &accMAG)
LOG_GROUP_STOP(acc)
</pre>
</code>
</blockquote>
::Just like in the magnetometer block, here we have created a log group called 'acc' and inside this group we are logging the variables for the accelerometer's X, Y, and Z values as well as 2 other gravity based variables used for thrust compensation.
===Using New Log Blocks in Swarm Client===
Now that we have these new log blocks in the Firmware, we can [[:Logging#New Client Log Blocks|use log blocks in the Client]]
==Modify the Default Yaw Mode==
There are 3 types of Yaw Modes available in the Firmware (as of 7/21/16), as shown (code in ''Firmware > modules > interface > commander.h'')
<blockquote>
<code>
<pre>
typedef enum
{
CAREFREE = 0, // Yaw is locked to world coordinates thus heading stays the same when yaw rotates
PLUSMODE = 1, // Plus-mode. Motor M1 is defined as front
XMODE = 2, // X-mode. M1 & M4 is defined as front
} YawModeType;
</pre>
</code>
</blockquote>
:'''Note:''' The default mode for the Crazyflie 2.0 is ''XMODE''. The ''PLUSMODE'' is default for the Crazyflie 1.0, but can still be used on the Crazyflie 2.0 if desired.
===Carefree Mode===
''CAREFREE'' mode is what our Crazyflie 2.0's are using, this mode applies a transformation to the Pitch and Roll setpoints depending on the angle of Yaw. We used to perform this calculation on the Client like this (code in ''eris_vrpn.cpp''):
<blockquote>
<code>
<pre>
#if USE_PR_YAW_CORRECT
//CORRECTS PITCH AND ROLL PID ERRORS TO ACCOUNT FOR QUADS CURRENT YAW DIRECTION (_/57.2958 converts DEG to RADIANS)
xError2 = cos(correctedYaw2 / 57.2958)*(xPositionDesired2 - xPosition2) - sin(correctedYaw2 / 57.2958)*(yPositionDesired2 - yPosition2);
yError2 = sin(correctedYaw2 / 57.2958)*(xPositionDesired2 - xPosition2) + cos(correctedYaw2 / 57.2958)*(yPositionDesired2 - yPosition2);
#else
xError2 = xPositionDesired2 - xPosition2;
yError2 = yPositionDesired2 - yPosition2;
#endif
controllerSetXYError(&pidCtrl2, xError2, yError2);
</pre>
</code>
</blockquote>
This is no longer necessary on the Client because this is the exact same calculation ''CAREFREE'' mode performs on the Firmware. So this reduces the computation done on the Client in each Crazyflie Callback.
====Changing Yaw Mode in Firmware====
To change the Yaw Mode to ''CAREFREE'' mode we had to make the modification shown (code in ''Firmware > modules > src > commander.c''):
<blockquote>
<code>
<pre>
***INSERT CODE CHANGE***
</pre>
</code>
</blockquote>
==New Firmware Parameter Groups==
Parameter groups are very similar to Log groups with a few key differences. An example of a Parameter group is shown (code in ''Firmware > modules > src > commander.c''):
:'''IMPORTANT:''' If you want to create new Parameter groups in a file, make sure you include <code>#include "param.h"</code> at the top of the file.
<blockquote>
<code>
<pre>
// Params for flight modes
PARAM_GROUP_START(flightmode)
PARAM_ADD(PARAM_UINT8, althold, &altHoldMode)
PARAM_ADD(PARAM_UINT8, yawMode, &yawMode)
PARAM_ADD(PARAM_UINT8, yawRst, &carefreeResetFront)
PARAM_ADD(PARAM_UINT8, stabModeRoll, &stabilizationModeRoll)
PARAM_ADD(PARAM_UINT8, stabModePitch, &stabilizationModePitch)
PARAM_ADD(PARAM_UINT8, stabModeYaw, &stabilizationModeYaw)
PARAM_GROUP_STOP(flightmode)
</pre>
</code>
</blockquote>
:So we create a parameter group called ''flightmode'' that contains the parameters listed. The difference between Log variables and Param variables is that for Param variables you need to specify the variable type (''PARAM_UINT8'' shown in the example).
Some User Friendly Param Types are shown below (you can find more complex Param types in ''Firmware > modules > interface > param.h'').
<blockquote>
<code>
<pre>
// User-friendly macros
#define PARAM_UINT8 (PARAM_1BYTE | PARAM_TYPE_INT | PARAM_UNSIGNED)
#define PARAM_INT8 (PARAM_1BYTE | PARAM_TYPE_INT | PARAM_SIGNED)
#define PARAM_UINT16 (PARAM_2BYTES | PARAM_TYPE_INT | PARAM_UNSIGNED)
#define PARAM_INT16 (PARAM_2BYTES | PARAM_TYPE_INT | PARAM_SIGNED)
#define PARAM_UINT32 (PARAM_4BYTES | PARAM_TYPE_INT | PARAM_UNSIGNED)
#define PARAM_INT32 (PARAM_4BYTES | PARAM_TYPE_INT | PARAM_SIGNED)
</pre>
</code>
</blockquote>
===Using Param Groups in Client===
This is not implemented yet (as of 7/21/16) but would be very nice to have.
If someone would like to attempt to create this you can see the Bitcraze Wiki page on the [https://wiki.bitcraze.io/doc:crazyflie:crtp:param Params Protocol] for help on how to implement this.
----
<center> '''Main Directory''' </center>
<center> [[Crazyflie Swarm|Crazyflie Swarm Home]] | [[PC Client Software]] | [[USB Radio]] | [[Firmware]] | [[FAQ]] </center>
<center> '''Modifications Directory''' </center>
<center> [[Controller]] | [[Logging]] | [[Keyboard Commands]] | [[USB Radio#Changing Radio Channel|Changing Radio Channel]] | [[Flight Modes]] | [[Callbacks]] | [[Adding a Crazyflie]] | [[Firmware]] </center>
1e5dc859f68b1233cdd841890a33a3aab03cd34e
125
124
2016-07-21T18:12:59Z
Jnoronha
3
/* Using Param Groups in Client */ added potential applications to Client Param system
wikitext
text/x-wiki
Not much work has been done in the Firmware yet (as of 7/20/16). The few things we have been able to successfully modify are:
#Creating New Log Blocks
#Modifying the Default Yaw Mode
#Adding and Modifying Parameter Values
==New Firmware Log Blocks==
In the Crazyflie Firmware there is a generalized logging framework that allows us to make any group of variables into a log block. It makes things very easy to log. Here are a few examples:
:'''IMPORTANT:''' If you want to create new Log groups in a file, make sure you include <code>#include "log.h"</code> at the top of the file.
:Ex. 1. Magnometer Log Block (code found in ''Firmware > modules > src > stabilizer.c'')
<blockquote>
<code>
<pre>
LOG_GROUP_START(mag)
LOG_ADD(LOG_FLOAT, x, &mag.x)
LOG_ADD(LOG_FLOAT, y, &mag.y)
LOG_ADD(LOG_FLOAT, z, &mag.z)
LOG_GROUP_STOP(mag)
</pre>
</code>
</blockquote>
::So with this code we have created a log block called 'mag' and it contains the X, Y, and Z measurements from the magnetometer sensor.
:Ex. 2. Accelerometer Log Block (code found in ''Firmware > modules > src > stabilizer.c'')
<blockquote>
<code>
<pre>
LOG_GROUP_START(acc)
LOG_ADD(LOG_FLOAT, x, &acc.x)
LOG_ADD(LOG_FLOAT, y, &acc.y)
LOG_ADD(LOG_FLOAT, z, &acc.z)
LOG_ADD(LOG_FLOAT, zw, &accWZ)
LOG_ADD(LOG_FLOAT, mag2, &accMAG)
LOG_GROUP_STOP(acc)
</pre>
</code>
</blockquote>
::Just like in the magnetometer block, here we have created a log group called 'acc' and inside this group we are logging the variables for the accelerometer's X, Y, and Z values as well as 2 other gravity based variables used for thrust compensation.
===Using New Log Blocks in Swarm Client===
Now that we have these new log blocks in the Firmware, we can [[:Logging#New Client Log Blocks|use log blocks in the Client]]
==Modify the Default Yaw Mode==
There are 3 types of Yaw Modes available in the Firmware (as of 7/21/16), as shown (code in ''Firmware > modules > interface > commander.h'')
<blockquote>
<code>
<pre>
typedef enum
{
CAREFREE = 0, // Yaw is locked to world coordinates thus heading stays the same when yaw rotates
PLUSMODE = 1, // Plus-mode. Motor M1 is defined as front
XMODE = 2, // X-mode. M1 & M4 is defined as front
} YawModeType;
</pre>
</code>
</blockquote>
:'''Note:''' The default mode for the Crazyflie 2.0 is ''XMODE''. The ''PLUSMODE'' is default for the Crazyflie 1.0, but can still be used on the Crazyflie 2.0 if desired.
===Carefree Mode===
''CAREFREE'' mode is what our Crazyflie 2.0's are using, this mode applies a transformation to the Pitch and Roll setpoints depending on the angle of Yaw. We used to perform this calculation on the Client like this (code in ''eris_vrpn.cpp''):
<blockquote>
<code>
<pre>
#if USE_PR_YAW_CORRECT
//CORRECTS PITCH AND ROLL PID ERRORS TO ACCOUNT FOR QUADS CURRENT YAW DIRECTION (_/57.2958 converts DEG to RADIANS)
xError2 = cos(correctedYaw2 / 57.2958)*(xPositionDesired2 - xPosition2) - sin(correctedYaw2 / 57.2958)*(yPositionDesired2 - yPosition2);
yError2 = sin(correctedYaw2 / 57.2958)*(xPositionDesired2 - xPosition2) + cos(correctedYaw2 / 57.2958)*(yPositionDesired2 - yPosition2);
#else
xError2 = xPositionDesired2 - xPosition2;
yError2 = yPositionDesired2 - yPosition2;
#endif
controllerSetXYError(&pidCtrl2, xError2, yError2);
</pre>
</code>
</blockquote>
This is no longer necessary on the Client because this is the exact same calculation ''CAREFREE'' mode performs on the Firmware. So this reduces the computation done on the Client in each Crazyflie Callback.
====Changing Yaw Mode in Firmware====
To change the Yaw Mode to ''CAREFREE'' mode we had to make the modification shown (code in ''Firmware > modules > src > commander.c''):
<blockquote>
<code>
<pre>
***INSERT CODE CHANGE***
</pre>
</code>
</blockquote>
==New Firmware Parameter Groups==
Parameter groups are very similar to Log groups with a few key differences. An example of a Parameter group is shown (code in ''Firmware > modules > src > commander.c''):
:'''IMPORTANT:''' If you want to create new Parameter groups in a file, make sure you include <code>#include "param.h"</code> at the top of the file.
<blockquote>
<code>
<pre>
// Params for flight modes
PARAM_GROUP_START(flightmode)
PARAM_ADD(PARAM_UINT8, althold, &altHoldMode)
PARAM_ADD(PARAM_UINT8, yawMode, &yawMode)
PARAM_ADD(PARAM_UINT8, yawRst, &carefreeResetFront)
PARAM_ADD(PARAM_UINT8, stabModeRoll, &stabilizationModeRoll)
PARAM_ADD(PARAM_UINT8, stabModePitch, &stabilizationModePitch)
PARAM_ADD(PARAM_UINT8, stabModeYaw, &stabilizationModeYaw)
PARAM_GROUP_STOP(flightmode)
</pre>
</code>
</blockquote>
:So we create a parameter group called ''flightmode'' that contains the parameters listed. The difference between Log variables and Param variables is that for Param variables you need to specify the variable type (''PARAM_UINT8'' shown in the example).
Some User Friendly Param Types are shown below (you can find more complex Param types in ''Firmware > modules > interface > param.h'').
<blockquote>
<code>
<pre>
// User-friendly macros
#define PARAM_UINT8 (PARAM_1BYTE | PARAM_TYPE_INT | PARAM_UNSIGNED)
#define PARAM_INT8 (PARAM_1BYTE | PARAM_TYPE_INT | PARAM_SIGNED)
#define PARAM_UINT16 (PARAM_2BYTES | PARAM_TYPE_INT | PARAM_UNSIGNED)
#define PARAM_INT16 (PARAM_2BYTES | PARAM_TYPE_INT | PARAM_SIGNED)
#define PARAM_UINT32 (PARAM_4BYTES | PARAM_TYPE_INT | PARAM_UNSIGNED)
#define PARAM_INT32 (PARAM_4BYTES | PARAM_TYPE_INT | PARAM_SIGNED)
</pre>
</code>
</blockquote>
===Using Param Groups in Client===
This is not implemented yet (as of 7/21/16) but would be very nice to have. We could then tune Firmware PID constants without needing to flash the Firmware each time and much more.
If someone would like to attempt to create this you can see the Bitcraze Wiki page on the [https://wiki.bitcraze.io/doc:crazyflie:crtp:param Params Protocol] for help on how to implement this.
----
<center> '''Main Directory''' </center>
<center> [[Crazyflie Swarm|Crazyflie Swarm Home]] | [[PC Client Software]] | [[USB Radio]] | [[Firmware]] | [[FAQ]] </center>
<center> '''Modifications Directory''' </center>
<center> [[Controller]] | [[Logging]] | [[Keyboard Commands]] | [[USB Radio#Changing Radio Channel|Changing Radio Channel]] | [[Flight Modes]] | [[Callbacks]] | [[Adding a Crazyflie]] | [[Firmware]] </center>
6c7d53aea4ca764fbe773469f8de180f9a20b678
FAQ
0
40
118
2016-07-20T18:23:34Z
Jnoronha
3
Added first few questions and directory
wikitext
text/x-wiki
Here you can find some Frequently Asked Questions:
:1. How do I change the Radio Channel?
::Find out here: [[:USB Radio#Changing Radio Channel|Changing the Radio Channel]]
:2. How do I use Log Blocks?
::*Creating and using [[:Logging#Client-Side External Log Files|External Client-side Log Files]]
::*Creating [[:Firmware#New Firmware Log Blocks|New Log Blocks in Firmware]]
::*Creating and Using [[:Logging#New Client Log Blocks|New Log Blocks in Client]]
:3.
----
<center> '''Main Directory''' </center>
<center> [[Crazyflie Swarm|Crazyflie Swarm Home]] | [[PC Client Software]] | [[USB Radio]] | [[Firmware]] | [[FAQ]] </center>
<center> '''Modifications Directory''' </center>
<center> [[Controller]] | [[Logging]] | [[Keyboard Commands]] | [[USB Radio#Changing Radio Channel|Changing Radio Channel]] | [[Flight Modes]] | [[Callbacks]] | [[Adding a Crazyflie]] | [[Firmware]] </center>
25bc2aae2645ae601c63447288f8106304219bc4
135
118
2016-07-22T17:32:03Z
Jnoronha
3
Added a couple more questions
wikitext
text/x-wiki
Here you can find some Frequently Asked Questions:
:1. How do I change the Radio Channel?
::Find out here: [[:USB Radio#Changing Radio Channel|Changing the Radio Channel]]
:2. How do I use Log Blocks?
::*Creating and using [[:Logging#Client-Side External Log Files|External Client-side Log Files]]
::*Creating [[:Firmware#New Firmware Log Blocks|New Log Blocks in Firmware]]
::*Creating and Using [[:Logging#New Client Log Blocks|New Log Blocks in Client]]
:3. I just want to run the code, how do I run it?
::See [[:PC Client Software#Using the Swarm Client|Using the Swarm Client]]
:4. What are the Keyboard Commands for flying the Crazyflie?
::You can find a full list of all the Key Commands in [[:Keyboard Commands]]
::(Alternatively: See '''Step 4''' of [[:PC Client Software#Using the Swarm Client|Using the Swarm Client]])
----
<center> '''Main Directory''' </center>
<center> [[Crazyflie Swarm|Crazyflie Swarm Home]] | [[PC Client Software]] | [[USB Radio]] | [[Firmware]] | [[FAQ]] </center>
<center> '''Modifications Directory''' </center>
<center> [[Controller]] | [[Logging]] | [[Keyboard Commands]] | [[USB Radio#Changing Radio Channel|Changing Radio Channel]] | [[Flight Modes]] | [[Callbacks]] | [[Adding a Crazyflie]] | [[Firmware]] </center>
75c2d00e31e1c3b729798eac25859c89d1e839e0
136
135
2016-07-22T17:33:45Z
Jnoronha
3
bolded questions
wikitext
text/x-wiki
Here you can find some Frequently Asked Questions:
:'''1. How do I change the Radio Channel?'''
::Find out here: [[:USB Radio#Changing Radio Channel|Changing the Radio Channel]]
:'''2. How do I use Log Blocks?'''
::*Creating and using [[:Logging#Client-Side External Log Files|External Client-side Log Files]]
::*Creating [[:Firmware#New Firmware Log Blocks|New Log Blocks in Firmware]]
::*Creating and Using [[:Logging#New Client Log Blocks|New Log Blocks in Client]]
:'''3. I just want to run the code, how do I run it?'''
::See [[:PC Client Software#Using the Swarm Client|Using the Swarm Client]]
:'''4. What are the Keyboard Commands for flying the Crazyflie?'''
::You can find a full list of all the Key Commands in [[:Keyboard Commands]]
::(Alternatively: See '''Step 4''' of [[:PC Client Software#Using the Swarm Client|Using the Swarm Client]])
----
<center> '''Main Directory''' </center>
<center> [[Crazyflie Swarm|Crazyflie Swarm Home]] | [[PC Client Software]] | [[USB Radio]] | [[Firmware]] | [[FAQ]] </center>
<center> '''Modifications Directory''' </center>
<center> [[Controller]] | [[Logging]] | [[Keyboard Commands]] | [[USB Radio#Changing Radio Channel|Changing Radio Channel]] | [[Flight Modes]] | [[Callbacks]] | [[Adding a Crazyflie]] | [[Firmware]] </center>
c132db8e6f9a754f6b95a90f29ff841bf7fc7917
PC Client Software
0
25
119
96
2016-07-20T18:58:11Z
Jnoronha
3
/* Using the Swarm Client */ added directory
wikitext
text/x-wiki
The PC Client software comes in many forms. The out-of-the-box Client is written in Python and has a Graphical User Interface (GUI). The GUI is well suited for beginners, but can only support a single Radio and a single Crazyflie at a time. The easiest way to start out is with the [https://wiki.bitcraze.io/projects:virtualmachine:index Bitcraze Virtual Machine (VM)], which comes with all the files and dependencies pre-installed and can run on any computer (Windows, Mac, Linux, etc.).
For more advanced users who want to use the swarm capabilities of our platform will have to use the [[#Swarm Client|Swarm Client]] we developed in C and C++.
==[https://wiki.bitcraze.io/projects:virtualmachine:index Bitcraze VM]==
('''Note:''' The VM is updated frequently so the information below may be different than the current VM)
The Bitcraze wiki has a tutorial on [https://wiki.bitcraze.io/projects:virtualmachine:tutorials:vmware-win7 installing the VM]. Along with another tutorial on how to get started [https://www.bitcraze.io/getting-started-with-development/ using the VM].
These are both very simple starting guides that will help you become familiar with the VM.
===Crazyflie Client GUI===
On the VM you can find the Crazyflie Client Graphical User Interface (GUI). To run the Client you want to open a terminal and navigate to <code>projects/''''FIND PATH''''</code> and then run the command <code>sudo ./bin/cfclient</code>
(Alternatively, you can use the desktop to navigate to the folder and open a terminal there)
Once you do that you should see something similar to this:
[[Image:DefaultCrazyflieGUIMainScreen.JPG|500px]]
This is the main screen of the Client GUI and there are many tabs and features that you can access directly from this screen.
The most important parts of this screen are the following:
#Connect Button
#Bootloader (Crazyflie Drop Down -> Bootloader)
#Plotter Tab
#Log Blocks Tab
#Parameters Tab
====Connect Button====
This is where you will scan for Crazyflies that are powered ON. All Crazyflies not already connected will show up in the popup
[[Image:DefaultCrazyflieGUIConnectScreen.JPG|400px]]
We get a return that says <code>radio://0/45/2M</code>, this line is the identifier string of the Crazyflie we are trying to connect to.
What this is saying is that we got a return from a Radio (Radio 0 specifically), from a Crazyflie on Channel 45 using a data rate of 2Mbps.
====Bootloader====
This where you can install new Firmware to the Crazyflie.
[[Image:DefaultCrazyflieGUIBootloader.JPG|500px]]
The first thing you'll need to update is to build the Firmware version you want into a .bin file. You can do this by just running the <code>make</code> command in terminal while located inside the Firmware directory you have modified.
Once you have that .bin file built you:
#Open the bootloader shown
#Hold down the power button on the Crazyflie 2.0 for around 3 seconds until the 2 blue LED's flash and alternate. This puts the Crazyflie in bootloader mode. ('''NOTE:''' Recommend having '''ALL other Crazyflies OFF''' or else it could accidentally flash both Crazyflies.)
#Then hit ''Initiate bootloader cold boot'' (it should connect to the Crazyflie in bootloader mode after a few seconds, Status will change from 'Not Connected' to 'Connected')
#Hit ''Browse'' and find the .bin file you built earlier.
#Then click ''Program'' and wait for the progress bar to complete.
#Restart the Crazyflie in Firmware mode and make sure it starts up normally, if something seems wrong just repeat steps 2 through 6 again.
====Logging Tab====
Once you connect to a Crazyflie you can monitor certain log variables that have been set up. You will see a plot of the data similar to this:
[[Image:DefaultCrazyflieGUILoggerScreen.JPG|400px]]
On this screen we can do the following things:
*Dropdown Menu at the top of the screen
**Select which log block you want to plot on screen.
*Scale the X-axis of the plot by:
**Range
**Number of Samples
**Time in Seconds
**Manually
*Scale the Y-axis by:
**Automatically
**Manual Range
====Parameters Tab====
This tab displays all the parameters currently set up on the Crazyflie Firmware. Once you connect to a Crazyflie it lists these parameters in a table format similar to below:
[[Image:DefaultCrazyflieGUIParametersScreen.JPG|400px]]
For each parameter we get its Name, Variable Type, Access Type (Read/Write), and its Current Value.
We can also modify the parameter values on this screen in real-time and the changes will be sent to the Crazyflie automatically.
('''Note:''' Any parameter changes made on this screen are NOT preserved when you turn OFF the Crazyflie.)
==Swarm Client==
The swarm Client is a re-creation of the Original Client but programmed in C and C++.
The benefit of this is that
*We use a unified language between Client and Firmware
*Easily migrate this platform to any linux distribution that can install the Crazyflie dependencies.
**Our platform code itself requires only the VRPN libraries and a generic C compiler.
===Using the Swarm Client===
The Swarm Client uses the terminal interface for User Input.
[[Image:CrazyflieTerminalInitial.png|400px]]
Here we see what the initial Terminal looks like before we do anything.
:1. The first thing you want to do before any testing is to run the <code>sudo make</code> command in the Swarm Client directory. (Yes, the 'sudo' is necessary)
::This will make sure you have all the necessary dependencies, that the code is error free, and then it will build an executable (.exe) file of the Swarm Client code. An error free make will look something like this:
::[[Image:CrazyflieTerminalPostMake.png|400px]]
::There will be warnings, but those don't cause any issues right now.
:2. Pre-Test Checklist
::*Camera System is Turned on and Crazyflie Trackables are opened and visible.
::*Radios are plugged into the USB Ports on the Client computer.
::*Crazyflies are ON and NOT in an Error State.
:3. Run the executable file using the command <code>sudo ./eris_vrpn</code> in the same directory (Yes, the 'sudo' is necessary). This will start the program initialization and a bunch of status info will flood the screen. You will know the program is ready for input when you see the following:
::[[Image:CrazyflieTerminalProgramStarted.png|400px]]
::This means that the Crazyflie yaw has been synchronized with the Camera system and they are ready to fly.
:4. Input a Keyboard Command
::This will depend on what you have programmed as the keyboard input commands. As of 7/19/16 we have the following Keyboard Commands active:
::*'1' - Rotates Yaw of Crazyflie1 +45 degrees
::*'2' - Rotates Yaw of Crazyflie1 -45 degrees
::*'q' - Ends Main Loop (OBSOLETE - Replaced with ctrl + c)
::*'e' - Landing Mode (for ALL Crazyflies)
::*'t' - Crazyflie1 Take-Off
::*'y' - Crazyflie2 Take-Off
::*'u' - Crazyflie3 Take-Off
::*'i' - Crazyflie4 Take-Off
::*'h' - Hand Gesture Mode (for ALL Crazyflies)
::*'m' - Mirror Mode (for ALL Crazyflies)
::*ctrl+c - Quits Program, performs all cleanup.
::An example of what this would look like in the Terminal is shown here:
::[[Image:CrazyflieTerminalKeyboardInput.png|400px]]
::So you can see we commanded all 4 Crazyflies to take off (t,y,u,i), then activated Landing Mode (e), then activated Hand Mode (h), and then Ended the Program (ctrl+c).
:5. End Program when finished (ctrl+c)
::This will end the program loop, print the current battery levels, and Delete the Radio pointers (shown at the end of the previous figure)
----
<center> '''Main Directory''' </center>
<center> [[Crazyflie Swarm|Crazyflie Swarm Home]] | [[PC Client Software]] | [[USB Radio]] | [[Firmware]] | [[FAQ]] </center>
<center> '''Modifications Directory''' </center>
<center> [[Controller]] | [[Logging]] | [[Keyboard Commands]] | [[USB Radio#Changing Radio Channel|Changing Radio Channel]] | [[Flight Modes]] | [[Callbacks]] | [[Adding a Crazyflie]] | [[Firmware]] </center>
c716bf36d41522eff524fa871c90001cfb5bd499
134
119
2016-07-22T17:30:46Z
Jnoronha
3
Added makefile section
wikitext
text/x-wiki
The PC Client software comes in many forms. The out-of-the-box Client is written in Python and has a Graphical User Interface (GUI). The GUI is well suited for beginners, but can only support a single Radio and a single Crazyflie at a time. The easiest way to start out is with the [https://wiki.bitcraze.io/projects:virtualmachine:index Bitcraze Virtual Machine (VM)], which comes with all the files and dependencies pre-installed and can run on any computer (Windows, Mac, Linux, etc.).
For more advanced users who want to use the swarm capabilities of our platform will have to use the [[#Swarm Client|Swarm Client]] we developed in C and C++.
==[https://wiki.bitcraze.io/projects:virtualmachine:index Bitcraze VM]==
('''Note:''' The VM is updated frequently so the information below may be different than the current VM)
The Bitcraze wiki has a tutorial on [https://wiki.bitcraze.io/projects:virtualmachine:tutorials:vmware-win7 installing the VM]. Along with another tutorial on how to get started [https://www.bitcraze.io/getting-started-with-development/ using the VM].
These are both very simple starting guides that will help you become familiar with the VM.
===Crazyflie Client GUI===
On the VM you can find the Crazyflie Client Graphical User Interface (GUI). To run the Client you want to open a terminal and navigate to <code>projects/''''FIND PATH''''</code> and then run the command <code>sudo ./bin/cfclient</code>
(Alternatively, you can use the desktop to navigate to the folder and open a terminal there)
Once you do that you should see something similar to this:
[[Image:DefaultCrazyflieGUIMainScreen.JPG|500px]]
This is the main screen of the Client GUI and there are many tabs and features that you can access directly from this screen.
The most important parts of this screen are the following:
#Connect Button
#Bootloader (Crazyflie Drop Down -> Bootloader)
#Plotter Tab
#Log Blocks Tab
#Parameters Tab
====Connect Button====
This is where you will scan for Crazyflies that are powered ON. All Crazyflies not already connected will show up in the popup
[[Image:DefaultCrazyflieGUIConnectScreen.JPG|400px]]
We get a return that says <code>radio://0/45/2M</code>, this line is the identifier string of the Crazyflie we are trying to connect to.
What this is saying is that we got a return from a Radio (Radio 0 specifically), from a Crazyflie on Channel 45 using a data rate of 2Mbps.
====Bootloader====
This where you can install new Firmware to the Crazyflie.
[[Image:DefaultCrazyflieGUIBootloader.JPG|500px]]
The first thing you'll need to update is to build the Firmware version you want into a .bin file. You can do this by just running the <code>make</code> command in terminal while located inside the Firmware directory you have modified.
Once you have that .bin file built you:
#Open the bootloader shown
#Hold down the power button on the Crazyflie 2.0 for around 3 seconds until the 2 blue LED's flash and alternate. This puts the Crazyflie in bootloader mode. ('''NOTE:''' Recommend having '''ALL other Crazyflies OFF''' or else it could accidentally flash both Crazyflies.)
#Then hit ''Initiate bootloader cold boot'' (it should connect to the Crazyflie in bootloader mode after a few seconds, Status will change from 'Not Connected' to 'Connected')
#Hit ''Browse'' and find the .bin file you built earlier.
#Then click ''Program'' and wait for the progress bar to complete.
#Restart the Crazyflie in Firmware mode and make sure it starts up normally, if something seems wrong just repeat steps 2 through 6 again.
====Logging Tab====
Once you connect to a Crazyflie you can monitor certain log variables that have been set up. You will see a plot of the data similar to this:
[[Image:DefaultCrazyflieGUILoggerScreen.JPG|400px]]
On this screen we can do the following things:
*Dropdown Menu at the top of the screen
**Select which log block you want to plot on screen.
*Scale the X-axis of the plot by:
**Range
**Number of Samples
**Time in Seconds
**Manually
*Scale the Y-axis by:
**Automatically
**Manual Range
====Parameters Tab====
This tab displays all the parameters currently set up on the Crazyflie Firmware. Once you connect to a Crazyflie it lists these parameters in a table format similar to below:
[[Image:DefaultCrazyflieGUIParametersScreen.JPG|400px]]
For each parameter we get its Name, Variable Type, Access Type (Read/Write), and its Current Value.
We can also modify the parameter values on this screen in real-time and the changes will be sent to the Crazyflie automatically.
('''Note:''' Any parameter changes made on this screen are NOT preserved when you turn OFF the Crazyflie.)
==Swarm Client==
The swarm Client is a re-creation of the Original Client but programmed in C and C++.
The benefit of this is that
*We use a unified language between Client and Firmware
*Easily migrate this platform to any linux distribution that can install the Crazyflie dependencies.
**Our platform code itself requires only the VRPN libraries and a generic C compiler.
===Using the Swarm Client===
The Swarm Client uses the terminal interface for User Input.
[[Image:CrazyflieTerminalInitial.png|400px]]
Here we see what the initial Terminal looks like before we do anything.
:1. The first thing you want to do before any testing is to run the <code>sudo make</code> command in the Swarm Client directory. (Yes, the 'sudo' is necessary)
::This will make sure you have all the necessary dependencies, that the code is error free, and then it will build an executable (.exe) file of the Swarm Client code. An error free make will look something like this:
::[[Image:CrazyflieTerminalPostMake.png|400px]]
::There will be warnings, but those don't cause any issues right now.
:2. Pre-Test Checklist
::*Camera System is Turned on and Crazyflie Trackables are opened and visible.
::*Radios are plugged into the USB Ports on the Client computer.
::*Crazyflies are ON and NOT in an Error State.
:3. Run the executable file using the command <code>sudo ./eris_vrpn</code> in the same directory (Yes, the 'sudo' is necessary). This will start the program initialization and a bunch of status info will flood the screen. You will know the program is ready for input when you see the following:
::[[Image:CrazyflieTerminalProgramStarted.png|400px]]
::This means that the Crazyflie yaw has been synchronized with the Camera system and they are ready to fly.
:4. Input a Keyboard Command
::This will depend on what you have programmed as the keyboard input commands. As of 7/19/16 we have the following Keyboard Commands active:
::*'1' - Rotates Yaw of Crazyflie1 +45 degrees
::*'2' - Rotates Yaw of Crazyflie1 -45 degrees
::*'q' - Ends Main Loop (OBSOLETE - Replaced with ctrl + c)
::*'e' - Landing Mode (for ALL Crazyflies)
::*'t' - Crazyflie1 Take-Off
::*'y' - Crazyflie2 Take-Off
::*'u' - Crazyflie3 Take-Off
::*'i' - Crazyflie4 Take-Off
::*'h' - Hand Gesture Mode (for ALL Crazyflies)
::*'m' - Mirror Mode (for ALL Crazyflies)
::*ctrl+c - Quits Program, performs all cleanup.
::An example of what this would look like in the Terminal is shown here:
::[[Image:CrazyflieTerminalKeyboardInput.png|400px]]
::So you can see we commanded all 4 Crazyflies to take off (t,y,u,i), then activated Landing Mode (e), then activated Hand Mode (h), and then Ended the Program (ctrl+c).
:5. End Program when finished (ctrl+c)
::This will end the program loop, print the current battery levels, and Delete the Radio pointers (shown at the end of the previous figure)
===Makefile===
----
<center> '''Main Directory''' </center>
<center> [[Crazyflie Swarm|Crazyflie Swarm Home]] | [[PC Client Software]] | [[USB Radio]] | [[Firmware]] | [[FAQ]] </center>
<center> '''Modifications Directory''' </center>
<center> [[Controller]] | [[Logging]] | [[Keyboard Commands]] | [[USB Radio#Changing Radio Channel|Changing Radio Channel]] | [[Flight Modes]] | [[Callbacks]] | [[Adding a Crazyflie]] | [[Firmware]] </center>
fd5faf5401083ff81eaa244fe8f4095bee974f95
USB Radio
0
6
120
57
2016-07-20T18:58:40Z
Jnoronha
3
/* How does it work? */ modified directory
wikitext
text/x-wiki
The USB Radio Dongle acts as the bridge between the Client and the Firmware. It sends control setpoints generated from the Client to the Firmware controllers, as well as receives sensor data from the Firmware to the Client for logging.
== Modifying the Radio ==
The Radio functions can be found in the [[CCrazyRadio.cpp]] source file.
=== Radio Initialization ===
The following steps are how to Initialize a Radio. This code is currently run at the start of <code> main </code> in [[eris_vrpn.cpp]]. The process below can be extended to '''any number of Radios''' (currently 2 Radios shown)
:1. Create CrazyRadio Pointers and Crazyflie Pointers
<blockquote>
<code>
<pre>
CCrazyRadio *crRadio1 = 0;
CCrazyRadio *crRadio2 = 0;
CCrazyflie *cflieCopter1 = 0;
CCrazyflie *cflieCopter2 = 0;
CCrazyflie *cflieCopter3 = 0;
CCrazyflie *cflieCopter4 = 0;
</pre>
</code>
</blockquote>
'''Note:''' You must have a pointer for EACH Radio you want to initialize.
:2. Initialize First CrazyRadio
<blockquote>
<code>
<pre>
crRadio1 = new CCrazyRadio(0); // dongle number (starting at 0)
if( crRadio1->startRadio() ) //assigns pointer to USB location
{
cflieCopter1 = new CCrazyflie(crRadio1, 5); //Assigns Crazyflie1 to Radio1 on Channel 5
cflieCopter2 = new CCrazyflie(crRadio1, 80); //Assigns Crazyflie2 to Radio1 on Channel 80
}
else
{
std::cerr << "Could not connect to dongle 1. Did you plug it in?" << std::endl;
exit(-1);
}
usleep(10000);
</pre>
</code>
</blockquote>
:3. Initialize Second CrazyRadio (repeat as necessary...)
<blockquote>
<code>
<pre>
crRadio2 = new CCrazyRadio(1); // dongle number
if( crRadio2->startRadio() )
{
cflieCopter3 = new CCrazyflie(crRadio2, 25); //Assigns Crazyflie3 to Radio2 on Channel 25
cflieCopter4 = new CCrazyflie(crRadio2, 45); //Assigns Crazyflie4 to Radio2 on Channel 45
}
else
{
std::cerr << "Could not connect to dongle 2. Did you plug it in?" << std::endl;
exit(-1);
}
usleep(10000);
</pre>
</code>
</blockquote>
:4. (OPTIONAL) Modify Radio Parameters
<blockquote>
<code>
<pre>
crRadio1->setARDTime(2000); //Sets Wait Time (in μs) between Packet Retries (**MUST BE IN INCREMENTS OF 250**)
crRadio1->setARC(0); //Sets Number of times Retries Packet Send
crRadio1->setPower(P_0DBM); //Sets Radio Power (See CCrazyRadio.h for allowed ENUM values)
</pre>
</code>
</blockquote>
:5. '''Always''' Delete Radio Pointers Before Ending Program
<blockquote>
<code>
<pre>
delete crRadio1;
delete crRadio2;
</pre>
</code>
</blockquote>
'''Note:''' If you don't delete the pointers then you need to unplug the Radio and plug it back into the USB!
====How does it work?====
The Radio initialization was originally only able to support a single Radio per computer and a single Crazyflie per Radio. This was a result of how the <code> openUSBDongle() </code> function was written.
Originally the code worked as follows:
[[Image:RadioSelectionOldToNew.png]]
The issue with this is that if you want to assign another Radio it will always point to the same USB address, thus the different Radio pointers <code> crRadio1 </code> and <code> crRadio2 </code> would point to the same Radio dongle. So we modified the <code> openUSBDongle() </code> to take in the number of Radios you want to start, and then initialize them with a loop.
=== Changing Radio Channel ===
Changing the Radio Channel is easy, all you need to do is call the function:
<blockquote>
<code>
<pre>
crRadio1->setChannel( cflieCopter1->radioChannel() ); //Sets Radio channel to whatever value cflieCopter1 was assigned (The input can be replaced with a constant if needed)
</pre>
</code>
</blockquote>
==== How does it work? ====
The low level implementation of the <code> setChannel </code> function looks like this:
<blockquote>
<code>
<pre>
void CCrazyRadio::setChannel(int nChannel) {
if( ALL_THE_DEBUG ) printf( "%s(nChannel:%d)\n", __FUNCTION__, nChannel );
this->writeControl(NULL, 0, 0x01, nChannel, 0);
}
</pre>
</code>
</blockquote>
Which is using a libusb command <code> writeControl </code> to find the specific USB address of the Radio and write a new Channel to that USB device. The specific values plugged into this function will need to be looked up if you plan on working at this level.
----
<center> '''Main Directory''' </center>
<center> [[Crazyflie Swarm|Crazyflie Swarm Home]] | [[PC Client Software]] | [[USB Radio]] | [[Firmware]] | [[FAQ]] </center>
<center> '''Modifications Directory''' </center>
<center> [[Controller]] | [[Logging]] | [[Keyboard Commands]] | [[USB Radio#Changing Radio Channel|Changing Radio Channel]] | [[Flight Modes]] | [[Callbacks]] | [[Adding a Crazyflie]] | [[Firmware]] </center>
d52969cee4da32fdd150f792c8e70b2fce9fae73
Controller
0
5
122
72
2016-07-20T18:59:24Z
Jnoronha
3
/* Calculating the PID's */ modified directory
wikitext
text/x-wiki
The Crazyflie platform is completely customizable when it comes to the control design. As long as the controller can be written in C or C++, we can implement it in the Platform. This applies to both the controllers run on the PC Client and the controllers run on the Firmware of the Crazyflie. Originally the only controllers in the Platform were Firmware PID's that controlled the angular position and rates of the Crazyflie for hand flight. The original controller layout can be seen here [[#Original PID Controllers (Angular Rotation)|Original PID's]].
Below you will find documentation on the different types of Controllers that have been applied to the platform, organized by their location in the Platform.
== Firmware ==
=== Original PID Controllers (Angular Rotation) ===
Directly on the Crazyflie Firmware there are 5 PID controllers as seen here:
[[Image:FirmwareOnlyPIDArchitecture.png|500px]]
The Pitch and Roll angular position PID's receive constant setpoints from some outside source (gamepad controller or automated controller). The outputs of those angular position controllers is then fed into the angular rate controllers as shown. This final output is then fed into the Motor Command block which converts the angular rate setpoints into motor commands.
----
===State Estimator (Not Implemented Yet)===
('''***NOT YET IMPLEMENTED***''')
Bitcraze is currently working on adding a state estimator onto the Firmware to handle control calculations instead of the PID.
The code is in place but the controller is not yet used as of '''7/13/16'''.
== PC Client ==
=== PID Controllers (Position and Yaw) ===
The first controller implemented on the Client were 4 PID controllers used to stabilize the Crazyflie's position in X, Y, and Z, and angular position in Yaw respectively. These PID's feed directly into the Firmware PID's as seen here:
[[Image:CompletePIDArchitectureFigure.png|500px]]
The controllers inside the red box are the original PID controllers located on the Firmware as shown above in the [[#Original PID Controllers (Angular Rotation)|Original PID's]].
====Initialize the PID's====
:1. To start we create a struct with all the necessary variables (code from ''pid.h''):
<blockquote>
<code>
<pre>
typedef struct
{
float desired; //< set point
float error; //< error
float prevError; //< previous error
float integ; //< integral
float deriv; //< derivative
float kp; //< proportional gain
float ki; //< integral gain
float kd; //< derivative gain
float outP; //< proportional output (debugging)
float outI; //< integral output (debugging)
float outD; //< derivative output (debugging)
float iLimit; //< integral limit
float iLimitLow; //< integral limit
float dt; //< delta-time dt
float angularLimit; //sets limit for how far Crazyflie can tip, to prevent flipping
float angularLimitLow; //^
float thrustLimit; //Sets upper limit for Thrust Output (60000?) **?
float thrustLimitLow; //Sets lower limit for thrust Output (10001)
} PidObject;
</pre>
</code>
</blockquote>
:2. To simplify scaling up the code to multiple Crazyflies, we will create a <code> ControllerObject </code> that contains multiple PID structs as shown (code in ''controller.h''):
<blockquote>
<code>
<pre>
typedef struct
{
PidObject pidRoll;
PidObject pidPitch;
PidObject pidYaw;
PidObject pidX;
PidObject pidY;
PidObject pidZ;
bool isInit;
} ControllerObject;
</pre>
</code>
</blockquote>
:3. Then we initialize the Objects to 0 at the start of each run (code in ''eris_vrpn.cpp''):
<blockquote>
<code>
<pre>
ControllerObject pidCtrl1 = { 0 }; // init all fields to zero
ControllerObject pidCtrl2 = { 0 }; // init all fields to zero
ControllerObject pidCtrl3 = { 0 }; // init all fields to zero
ControllerObject pidCtrl4 = { 0 }; // init all fields to zero
</pre>
</code>
</blockquote>
:4. Then populate the PidObjects with the desired parameters (code in ''pid.c''):
<blockquote>
<code>
<pre>
void pidInit(PidObject* pid, const float desired, const float kp,
const float ki, const float kd, const float dt)
{
pid->error = 0;
pid->prevError = 0;
pid->integ = 0;
pid->deriv = 0;
pid->desired = desired;
pid->kp = kp;
pid->ki = ki;
pid->kd = kd;
pid->iLimit = DEFAULT_PID_INTEGRATION_LIMIT;
pid->iLimitLow = -DEFAULT_PID_INTEGRATION_LIMIT;
pid->angularLimit = DEFAULT_PID_ANGLE_OUTPUT;
pid->angularLimitLow = -DEFAULT_PID_ANGLE_OUTPUT;
pid->thrustLimit = DEFAULT_PID_HIGH_THRUST_LIMIT;
pid->thrustLimitLow = DEFAULT_PID_LOW_THRUST_LIMIT;
pid->dt = dt;
}
</pre>
</code>
</blockquote>
Using the above function for each of the <code>PidObjects</code> inside of the <code>ControllerObject</code> below (code in ''controller.c''):
<blockquote>
<code>
<pre>
void controllerInit( ControllerObject * ctrl )
{
if(ctrl->isInit)
return;
pidInit(&ctrl->pidY, 0, PID_Y_KP, PID_Y_KI, PID_Y_KD, CAMERA_UPDATE_DT); //for Roll PID
pidInit(&ctrl->pidX, 0, PID_X_KP, PID_X_KI, PID_X_KD, CAMERA_UPDATE_DT); //for Pitch PID
pidInit(&ctrl->pidYaw, 0, PID_YAW_KP, PID_YAW_KI, PID_YAW_KD, CAMERA_UPDATE_DT);
pidInit(&ctrl->pidZ, 0, PID_Z_KP, PID_Z_KI, PID_Z_KD, CAMERA_UPDATE_DT);
pidSetIntegralLimit(&ctrl->pidY, PID_Y_INTEGRATION_LIMIT);
pidSetIntegralLimit(&ctrl->pidX, PID_X_INTEGRATION_LIMIT);
pidSetIntegralLimit(&ctrl->pidYaw, PID_YAW_INTEGRATION_LIMIT);
pidSetIntegralLimit(&ctrl->pidZ, PID_Z_INTEGRATION_LIMIT);
ctrl->isInit = true;
}
</pre>
</code>
</blockquote>
'''Note:''' If we have multiple Crazyflies we need a <code>ControllerObject</code> for each Crazyflie (code in ''eris_vrpn.cpp'')
<blockquote>
<code>
<pre>
controllerResetAllPID( &pidCtrl1 );
controllerInit( &pidCtrl1 );
#endif
#if NUM_QUADS >= 2
controllerResetAllPID( &pidCtrl2 );
controllerInit( &pidCtrl2 );
#endif
#if NUM_QUADS >=3
controllerResetAllPID( &pidCtrl3 );
controllerInit( &pidCtrl3 );
#endif
#if NUM_QUADS >=4
controllerResetAllPID( &pidCtrl4 );
controllerInit( &pidCtrl4 );
#endif
</pre>
</code>
</blockquote>
Now the initialization of the Controllers is complete.
====Calculating the PID's====
:1. Each loop we want to calculate the PID output (code in ''pid.c''):
<blockquote>
<code>
<pre>
float pidUpdateAngle(PidObject* pid, const float measured, const bool updateError) //**USED FOR ATTITUDE CONTROL
{
float output;
if(updateError)
{
pid->error = pid->desired - measured; //Calculates current error
}
pid->integ += pid->error * pid->dt; //Calculates integral term
if(pid->integ > pid->iLimit) //Checks that the integral term stays below the integral limit (anti-windup)
{
pid->integ = pid->iLimit;
}
else if(pid->integ < pid->iLimitLow)
{
pid->integ = pid->iLimitLow;
}
pid->deriv = (pid->error - pid->prevError) / pid->dt; //Calculates derivative term
pid->outP = pid->kp* pid->error;
pid->outI = pid->ki * pid->integ;
pid->outD = pid->kd * pid->deriv;
output = pid->outP + pid->outI + pid->outD; //Adds up all 3 calculated terms for output
if(output > pid->angularLimit) //Limits amount Crazyflie can tip
{
output = pid->angularLimit;
}
if(output < pid->angularLimitLow) //Limits amount Crazyflie can tip
{
output = pid->angularLimitLow;
}
pid->prevError = pid->error; //Stores the current error for next loop
return output;
}
</pre>
</code>
</blockquote>
'''Note:''' There are 3 different versions of this Function (for Angle, Thrust, and Yaw) since each has different output limits.
:2. Using the function above, combine all PID calculations into one function (code in ''controller.c''):
<blockquote>
<code>
<pre>
void controllerCorrectAttitudePID(ControllerObject * ctrl,
float xPositionActual, float yPositionActual, float zPositionActual, float eulerYawActual, float xPositionDesired, float yPositionDesired,
float zPositionDesired, float eulerYawDesired, float* rollControlOutput, float* pitchControlOutput, float* yawControlOutput, float* thrustControlOutput)
{
pidSetDesired(&ctrl->pidX, xPositionDesired);
*pitchControlOutput = pidUpdateAngle(&ctrl->pidX, xPositionActual, false); //Originally true
pidSetDesired(&ctrl->pidY, yPositionDesired);
*rollControlOutput = pidUpdateAngle(&ctrl->pidY, yPositionActual, false); //Originally true
pidSetDesired(&ctrl->pidZ, zPositionDesired);
*thrustControlOutput = pidUpdateThrust(&ctrl->pidZ,zPositionActual, true);
float yawError;
pidSetDesired(&ctrl->pidYaw, eulerYawDesired);
yawError = eulerYawDesired - eulerYawActual;
if(yawError > 180.0) //Ensures Yaw error stays between -180 and 180 degrees
yawError -= 360.0;
else if(yawError < -180.0)
yawError += 360.0;
pidSetError(&ctrl->pidYaw, yawError);
*yawControlOutput = pidUpdateYaw(&ctrl->pidYaw, eulerYawActual, true); //originally false
}
</pre>
</code>
</blockquote>
:3. In each Callback, calculate the Controller outputs, assigned to pointer values<code>*rollControlOutput</code>, <code>*pitchControlOutput</code>, etc... (code in ''eris_vrpn.cpp''):
<blockquote>
<code>
<pre>
xError1 = xPositionDesired1 - xPosition1;
yError1 = yPositionDesired1 - yPosition1; //Calculates error externally
controllerSetXYError(&pidCtrl1, xError1, yError1);
controllerCorrectAttitudePID(&pidCtrl1, t.pos[0], t.pos[1], zPosition1, correctedYaw1,
xPositionDesired1, yPositionDesired1, zPositionDesired1,
yawDesired1, &rollControlOutput1, &pitchControlOutput1,
&yawControlOutput1, &thrustControlOutput1);
</pre>
</code>
</blockquote>
'''Note:''' We calculate error externally for X and Y because certain swarm controllers need special setpoint modifiers (this way we can switch modes without effecting the default setpoint):
'''Example:''' Follow Hand Mode Error (Crazyflie1 will have setpoint -0.5 m lower in X and +0.5 m higher in Y than your hand trackable):
<blockquote>
<code>
<pre>
...
xError1 = (xPositionHand - 0.5) - xPosition1;
yError1 = (yPositionHand + 0.5) - yPosition1;
controllerSetXYError(&pidCtrl1, xError1, yError1);
...
</pre>
</code>
</blockquote>
:4. Repeat for each set of new location data...
----
<center> '''Main Directory''' </center>
<center> [[Crazyflie Swarm|Crazyflie Swarm Home]] | [[PC Client Software]] | [[USB Radio]] | [[Firmware]] | [[FAQ]] </center>
<center> '''Modifications Directory''' </center>
<center> [[Controller]] | [[Logging]] | [[Keyboard Commands]] | [[USB Radio#Changing Radio Channel|Changing Radio Channel]] | [[Flight Modes]] | [[Callbacks]] | [[Adding a Crazyflie]] | [[Firmware]] </center>
8f3235d5554038d328eb6f8c86fe60119e97b130
131
122
2016-07-21T18:53:43Z
Jnoronha
3
/* Calculating the PID's */ formatting tabs
wikitext
text/x-wiki
The Crazyflie platform is completely customizable when it comes to the control design. As long as the controller can be written in C or C++, we can implement it in the Platform. This applies to both the controllers run on the PC Client and the controllers run on the Firmware of the Crazyflie. Originally the only controllers in the Platform were Firmware PID's that controlled the angular position and rates of the Crazyflie for hand flight. The original controller layout can be seen here [[#Original PID Controllers (Angular Rotation)|Original PID's]].
Below you will find documentation on the different types of Controllers that have been applied to the platform, organized by their location in the Platform.
== Firmware ==
=== Original PID Controllers (Angular Rotation) ===
Directly on the Crazyflie Firmware there are 5 PID controllers as seen here:
[[Image:FirmwareOnlyPIDArchitecture.png|500px]]
The Pitch and Roll angular position PID's receive constant setpoints from some outside source (gamepad controller or automated controller). The outputs of those angular position controllers is then fed into the angular rate controllers as shown. This final output is then fed into the Motor Command block which converts the angular rate setpoints into motor commands.
----
===State Estimator (Not Implemented Yet)===
('''***NOT YET IMPLEMENTED***''')
Bitcraze is currently working on adding a state estimator onto the Firmware to handle control calculations instead of the PID.
The code is in place but the controller is not yet used as of '''7/13/16'''.
== PC Client ==
=== PID Controllers (Position and Yaw) ===
The first controller implemented on the Client were 4 PID controllers used to stabilize the Crazyflie's position in X, Y, and Z, and angular position in Yaw respectively. These PID's feed directly into the Firmware PID's as seen here:
[[Image:CompletePIDArchitectureFigure.png|500px]]
The controllers inside the red box are the original PID controllers located on the Firmware as shown above in the [[#Original PID Controllers (Angular Rotation)|Original PID's]].
====Initialize the PID's====
:1. To start we create a struct with all the necessary variables (code from ''pid.h''):
<blockquote>
<code>
<pre>
typedef struct
{
float desired; //< set point
float error; //< error
float prevError; //< previous error
float integ; //< integral
float deriv; //< derivative
float kp; //< proportional gain
float ki; //< integral gain
float kd; //< derivative gain
float outP; //< proportional output (debugging)
float outI; //< integral output (debugging)
float outD; //< derivative output (debugging)
float iLimit; //< integral limit
float iLimitLow; //< integral limit
float dt; //< delta-time dt
float angularLimit; //sets limit for how far Crazyflie can tip, to prevent flipping
float angularLimitLow; //^
float thrustLimit; //Sets upper limit for Thrust Output (60000?) **?
float thrustLimitLow; //Sets lower limit for thrust Output (10001)
} PidObject;
</pre>
</code>
</blockquote>
:2. To simplify scaling up the code to multiple Crazyflies, we will create a <code> ControllerObject </code> that contains multiple PID structs as shown (code in ''controller.h''):
<blockquote>
<code>
<pre>
typedef struct
{
PidObject pidRoll;
PidObject pidPitch;
PidObject pidYaw;
PidObject pidX;
PidObject pidY;
PidObject pidZ;
bool isInit;
} ControllerObject;
</pre>
</code>
</blockquote>
:3. Then we initialize the Objects to 0 at the start of each run (code in ''eris_vrpn.cpp''):
<blockquote>
<code>
<pre>
ControllerObject pidCtrl1 = { 0 }; // init all fields to zero
ControllerObject pidCtrl2 = { 0 }; // init all fields to zero
ControllerObject pidCtrl3 = { 0 }; // init all fields to zero
ControllerObject pidCtrl4 = { 0 }; // init all fields to zero
</pre>
</code>
</blockquote>
:4. Then populate the PidObjects with the desired parameters (code in ''pid.c''):
<blockquote>
<code>
<pre>
void pidInit(PidObject* pid, const float desired, const float kp,
const float ki, const float kd, const float dt)
{
pid->error = 0;
pid->prevError = 0;
pid->integ = 0;
pid->deriv = 0;
pid->desired = desired;
pid->kp = kp;
pid->ki = ki;
pid->kd = kd;
pid->iLimit = DEFAULT_PID_INTEGRATION_LIMIT;
pid->iLimitLow = -DEFAULT_PID_INTEGRATION_LIMIT;
pid->angularLimit = DEFAULT_PID_ANGLE_OUTPUT;
pid->angularLimitLow = -DEFAULT_PID_ANGLE_OUTPUT;
pid->thrustLimit = DEFAULT_PID_HIGH_THRUST_LIMIT;
pid->thrustLimitLow = DEFAULT_PID_LOW_THRUST_LIMIT;
pid->dt = dt;
}
</pre>
</code>
</blockquote>
Using the above function for each of the <code>PidObjects</code> inside of the <code>ControllerObject</code> below (code in ''controller.c''):
<blockquote>
<code>
<pre>
void controllerInit( ControllerObject * ctrl )
{
if(ctrl->isInit)
return;
pidInit(&ctrl->pidY, 0, PID_Y_KP, PID_Y_KI, PID_Y_KD, CAMERA_UPDATE_DT); //for Roll PID
pidInit(&ctrl->pidX, 0, PID_X_KP, PID_X_KI, PID_X_KD, CAMERA_UPDATE_DT); //for Pitch PID
pidInit(&ctrl->pidYaw, 0, PID_YAW_KP, PID_YAW_KI, PID_YAW_KD, CAMERA_UPDATE_DT);
pidInit(&ctrl->pidZ, 0, PID_Z_KP, PID_Z_KI, PID_Z_KD, CAMERA_UPDATE_DT);
pidSetIntegralLimit(&ctrl->pidY, PID_Y_INTEGRATION_LIMIT);
pidSetIntegralLimit(&ctrl->pidX, PID_X_INTEGRATION_LIMIT);
pidSetIntegralLimit(&ctrl->pidYaw, PID_YAW_INTEGRATION_LIMIT);
pidSetIntegralLimit(&ctrl->pidZ, PID_Z_INTEGRATION_LIMIT);
ctrl->isInit = true;
}
</pre>
</code>
</blockquote>
'''Note:''' If we have multiple Crazyflies we need a <code>ControllerObject</code> for each Crazyflie (code in ''eris_vrpn.cpp'')
<blockquote>
<code>
<pre>
controllerResetAllPID( &pidCtrl1 );
controllerInit( &pidCtrl1 );
#endif
#if NUM_QUADS >= 2
controllerResetAllPID( &pidCtrl2 );
controllerInit( &pidCtrl2 );
#endif
#if NUM_QUADS >=3
controllerResetAllPID( &pidCtrl3 );
controllerInit( &pidCtrl3 );
#endif
#if NUM_QUADS >=4
controllerResetAllPID( &pidCtrl4 );
controllerInit( &pidCtrl4 );
#endif
</pre>
</code>
</blockquote>
Now the initialization of the Controllers is complete.
====Calculating the PID's====
:1. Each loop we want to calculate the PID output (code in ''pid.c''):
<blockquote>
<code>
<pre>
float pidUpdateAngle(PidObject* pid, const float measured, const bool updateError) //**USED FOR ATTITUDE CONTROL
{
float output;
if(updateError)
{
pid->error = pid->desired - measured; //Calculates current error
}
pid->integ += pid->error * pid->dt; //Calculates integral term
if(pid->integ > pid->iLimit) //Checks that the integral term stays below the integral limit (anti-windup)
{
pid->integ = pid->iLimit;
}
else if(pid->integ < pid->iLimitLow)
{
pid->integ = pid->iLimitLow;
}
pid->deriv = (pid->error - pid->prevError) / pid->dt; //Calculates derivative term
pid->outP = pid->kp* pid->error;
pid->outI = pid->ki * pid->integ;
pid->outD = pid->kd * pid->deriv;
output = pid->outP + pid->outI + pid->outD; //Adds up all 3 calculated terms for output
if(output > pid->angularLimit) //Limits amount Crazyflie can tip
{
output = pid->angularLimit;
}
if(output < pid->angularLimitLow) //Limits amount Crazyflie can tip
{
output = pid->angularLimitLow;
}
pid->prevError = pid->error; //Stores the current error for next loop
return output;
}
</pre>
</code>
</blockquote>
::'''Note:''' There are 3 different versions of this Function (for Angle, Thrust, and Yaw) since each has different output limits.
:2. Using the function above, combine all PID calculations into one function (code in ''controller.c''):
<blockquote>
<code>
<pre>
void controllerCorrectAttitudePID(ControllerObject * ctrl,
float xPositionActual, float yPositionActual, float zPositionActual, float eulerYawActual, float xPositionDesired, float yPositionDesired,
float zPositionDesired, float eulerYawDesired, float* rollControlOutput, float* pitchControlOutput, float* yawControlOutput, float* thrustControlOutput)
{
pidSetDesired(&ctrl->pidX, xPositionDesired);
*pitchControlOutput = pidUpdateAngle(&ctrl->pidX, xPositionActual, false); //Originally true
pidSetDesired(&ctrl->pidY, yPositionDesired);
*rollControlOutput = pidUpdateAngle(&ctrl->pidY, yPositionActual, false); //Originally true
pidSetDesired(&ctrl->pidZ, zPositionDesired);
*thrustControlOutput = pidUpdateThrust(&ctrl->pidZ,zPositionActual, true);
float yawError;
pidSetDesired(&ctrl->pidYaw, eulerYawDesired);
yawError = eulerYawDesired - eulerYawActual;
if(yawError > 180.0) //Ensures Yaw error stays between -180 and 180 degrees
yawError -= 360.0;
else if(yawError < -180.0)
yawError += 360.0;
pidSetError(&ctrl->pidYaw, yawError);
*yawControlOutput = pidUpdateYaw(&ctrl->pidYaw, eulerYawActual, true); //originally false
}
</pre>
</code>
</blockquote>
:3. In each Callback, calculate the Controller outputs, assigned to pointer values<code>*rollControlOutput</code>, <code>*pitchControlOutput</code>, etc... (code in ''eris_vrpn.cpp''):
<blockquote>
<code>
<pre>
xError1 = xPositionDesired1 - xPosition1;
yError1 = yPositionDesired1 - yPosition1; //Calculates error externally
controllerSetXYError(&pidCtrl1, xError1, yError1);
controllerCorrectAttitudePID(&pidCtrl1, t.pos[0], t.pos[1], zPosition1, correctedYaw1,
xPositionDesired1, yPositionDesired1, zPositionDesired1,
yawDesired1, &rollControlOutput1, &pitchControlOutput1,
&yawControlOutput1, &thrustControlOutput1);
</pre>
</code>
</blockquote>
::'''Note:''' We calculate error externally for X and Y because certain swarm controllers need special setpoint modifiers (this way we can switch modes without effecting the default setpoint):
::'''Example:''' Follow Hand Mode Error (Crazyflie1 will have setpoint -0.5 m lower in X and +0.5 m higher in Y than your hand trackable):
<blockquote>
<code>
<pre>
...
xError1 = (xPositionHand - 0.5) - xPosition1;
yError1 = (yPositionHand + 0.5) - yPosition1;
controllerSetXYError(&pidCtrl1, xError1, yError1);
...
</pre>
</code>
</blockquote>
:4. Repeat for each set of new location data...until Program END.
----
<center> '''Main Directory''' </center>
<center> [[Crazyflie Swarm|Crazyflie Swarm Home]] | [[PC Client Software]] | [[USB Radio]] | [[Firmware]] | [[FAQ]] </center>
<center> '''Modifications Directory''' </center>
<center> [[Controller]] | [[Logging]] | [[Keyboard Commands]] | [[USB Radio#Changing Radio Channel|Changing Radio Channel]] | [[Flight Modes]] | [[Callbacks]] | [[Adding a Crazyflie]] | [[Firmware]] </center>
6f011366331e5775b63fa07627dbb38ea4bdca46
132
131
2016-07-21T18:54:23Z
Jnoronha
3
/* PID Controllers (Position and Yaw) */ changed heading to specify Client
wikitext
text/x-wiki
The Crazyflie platform is completely customizable when it comes to the control design. As long as the controller can be written in C or C++, we can implement it in the Platform. This applies to both the controllers run on the PC Client and the controllers run on the Firmware of the Crazyflie. Originally the only controllers in the Platform were Firmware PID's that controlled the angular position and rates of the Crazyflie for hand flight. The original controller layout can be seen here [[#Original PID Controllers (Angular Rotation)|Original PID's]].
Below you will find documentation on the different types of Controllers that have been applied to the platform, organized by their location in the Platform.
== Firmware ==
=== Original PID Controllers (Angular Rotation) ===
Directly on the Crazyflie Firmware there are 5 PID controllers as seen here:
[[Image:FirmwareOnlyPIDArchitecture.png|500px]]
The Pitch and Roll angular position PID's receive constant setpoints from some outside source (gamepad controller or automated controller). The outputs of those angular position controllers is then fed into the angular rate controllers as shown. This final output is then fed into the Motor Command block which converts the angular rate setpoints into motor commands.
----
===State Estimator (Not Implemented Yet)===
('''***NOT YET IMPLEMENTED***''')
Bitcraze is currently working on adding a state estimator onto the Firmware to handle control calculations instead of the PID.
The code is in place but the controller is not yet used as of '''7/13/16'''.
== PC Client ==
=== Client PID Controllers (Position and Yaw) ===
The first controller implemented on the Client were 4 PID controllers used to stabilize the Crazyflie's position in X, Y, and Z, and angular position in Yaw respectively. These PID's feed directly into the Firmware PID's as seen here:
[[Image:CompletePIDArchitectureFigure.png|500px]]
The controllers inside the red box are the original PID controllers located on the Firmware as shown above in the [[#Original PID Controllers (Angular Rotation)|Original PID's]].
====Initialize the PID's====
:1. To start we create a struct with all the necessary variables (code from ''pid.h''):
<blockquote>
<code>
<pre>
typedef struct
{
float desired; //< set point
float error; //< error
float prevError; //< previous error
float integ; //< integral
float deriv; //< derivative
float kp; //< proportional gain
float ki; //< integral gain
float kd; //< derivative gain
float outP; //< proportional output (debugging)
float outI; //< integral output (debugging)
float outD; //< derivative output (debugging)
float iLimit; //< integral limit
float iLimitLow; //< integral limit
float dt; //< delta-time dt
float angularLimit; //sets limit for how far Crazyflie can tip, to prevent flipping
float angularLimitLow; //^
float thrustLimit; //Sets upper limit for Thrust Output (60000?) **?
float thrustLimitLow; //Sets lower limit for thrust Output (10001)
} PidObject;
</pre>
</code>
</blockquote>
:2. To simplify scaling up the code to multiple Crazyflies, we will create a <code> ControllerObject </code> that contains multiple PID structs as shown (code in ''controller.h''):
<blockquote>
<code>
<pre>
typedef struct
{
PidObject pidRoll;
PidObject pidPitch;
PidObject pidYaw;
PidObject pidX;
PidObject pidY;
PidObject pidZ;
bool isInit;
} ControllerObject;
</pre>
</code>
</blockquote>
:3. Then we initialize the Objects to 0 at the start of each run (code in ''eris_vrpn.cpp''):
<blockquote>
<code>
<pre>
ControllerObject pidCtrl1 = { 0 }; // init all fields to zero
ControllerObject pidCtrl2 = { 0 }; // init all fields to zero
ControllerObject pidCtrl3 = { 0 }; // init all fields to zero
ControllerObject pidCtrl4 = { 0 }; // init all fields to zero
</pre>
</code>
</blockquote>
:4. Then populate the PidObjects with the desired parameters (code in ''pid.c''):
<blockquote>
<code>
<pre>
void pidInit(PidObject* pid, const float desired, const float kp,
const float ki, const float kd, const float dt)
{
pid->error = 0;
pid->prevError = 0;
pid->integ = 0;
pid->deriv = 0;
pid->desired = desired;
pid->kp = kp;
pid->ki = ki;
pid->kd = kd;
pid->iLimit = DEFAULT_PID_INTEGRATION_LIMIT;
pid->iLimitLow = -DEFAULT_PID_INTEGRATION_LIMIT;
pid->angularLimit = DEFAULT_PID_ANGLE_OUTPUT;
pid->angularLimitLow = -DEFAULT_PID_ANGLE_OUTPUT;
pid->thrustLimit = DEFAULT_PID_HIGH_THRUST_LIMIT;
pid->thrustLimitLow = DEFAULT_PID_LOW_THRUST_LIMIT;
pid->dt = dt;
}
</pre>
</code>
</blockquote>
Using the above function for each of the <code>PidObjects</code> inside of the <code>ControllerObject</code> below (code in ''controller.c''):
<blockquote>
<code>
<pre>
void controllerInit( ControllerObject * ctrl )
{
if(ctrl->isInit)
return;
pidInit(&ctrl->pidY, 0, PID_Y_KP, PID_Y_KI, PID_Y_KD, CAMERA_UPDATE_DT); //for Roll PID
pidInit(&ctrl->pidX, 0, PID_X_KP, PID_X_KI, PID_X_KD, CAMERA_UPDATE_DT); //for Pitch PID
pidInit(&ctrl->pidYaw, 0, PID_YAW_KP, PID_YAW_KI, PID_YAW_KD, CAMERA_UPDATE_DT);
pidInit(&ctrl->pidZ, 0, PID_Z_KP, PID_Z_KI, PID_Z_KD, CAMERA_UPDATE_DT);
pidSetIntegralLimit(&ctrl->pidY, PID_Y_INTEGRATION_LIMIT);
pidSetIntegralLimit(&ctrl->pidX, PID_X_INTEGRATION_LIMIT);
pidSetIntegralLimit(&ctrl->pidYaw, PID_YAW_INTEGRATION_LIMIT);
pidSetIntegralLimit(&ctrl->pidZ, PID_Z_INTEGRATION_LIMIT);
ctrl->isInit = true;
}
</pre>
</code>
</blockquote>
'''Note:''' If we have multiple Crazyflies we need a <code>ControllerObject</code> for each Crazyflie (code in ''eris_vrpn.cpp'')
<blockquote>
<code>
<pre>
controllerResetAllPID( &pidCtrl1 );
controllerInit( &pidCtrl1 );
#endif
#if NUM_QUADS >= 2
controllerResetAllPID( &pidCtrl2 );
controllerInit( &pidCtrl2 );
#endif
#if NUM_QUADS >=3
controllerResetAllPID( &pidCtrl3 );
controllerInit( &pidCtrl3 );
#endif
#if NUM_QUADS >=4
controllerResetAllPID( &pidCtrl4 );
controllerInit( &pidCtrl4 );
#endif
</pre>
</code>
</blockquote>
Now the initialization of the Controllers is complete.
====Calculating the PID's====
:1. Each loop we want to calculate the PID output (code in ''pid.c''):
<blockquote>
<code>
<pre>
float pidUpdateAngle(PidObject* pid, const float measured, const bool updateError) //**USED FOR ATTITUDE CONTROL
{
float output;
if(updateError)
{
pid->error = pid->desired - measured; //Calculates current error
}
pid->integ += pid->error * pid->dt; //Calculates integral term
if(pid->integ > pid->iLimit) //Checks that the integral term stays below the integral limit (anti-windup)
{
pid->integ = pid->iLimit;
}
else if(pid->integ < pid->iLimitLow)
{
pid->integ = pid->iLimitLow;
}
pid->deriv = (pid->error - pid->prevError) / pid->dt; //Calculates derivative term
pid->outP = pid->kp* pid->error;
pid->outI = pid->ki * pid->integ;
pid->outD = pid->kd * pid->deriv;
output = pid->outP + pid->outI + pid->outD; //Adds up all 3 calculated terms for output
if(output > pid->angularLimit) //Limits amount Crazyflie can tip
{
output = pid->angularLimit;
}
if(output < pid->angularLimitLow) //Limits amount Crazyflie can tip
{
output = pid->angularLimitLow;
}
pid->prevError = pid->error; //Stores the current error for next loop
return output;
}
</pre>
</code>
</blockquote>
::'''Note:''' There are 3 different versions of this Function (for Angle, Thrust, and Yaw) since each has different output limits.
:2. Using the function above, combine all PID calculations into one function (code in ''controller.c''):
<blockquote>
<code>
<pre>
void controllerCorrectAttitudePID(ControllerObject * ctrl,
float xPositionActual, float yPositionActual, float zPositionActual, float eulerYawActual, float xPositionDesired, float yPositionDesired,
float zPositionDesired, float eulerYawDesired, float* rollControlOutput, float* pitchControlOutput, float* yawControlOutput, float* thrustControlOutput)
{
pidSetDesired(&ctrl->pidX, xPositionDesired);
*pitchControlOutput = pidUpdateAngle(&ctrl->pidX, xPositionActual, false); //Originally true
pidSetDesired(&ctrl->pidY, yPositionDesired);
*rollControlOutput = pidUpdateAngle(&ctrl->pidY, yPositionActual, false); //Originally true
pidSetDesired(&ctrl->pidZ, zPositionDesired);
*thrustControlOutput = pidUpdateThrust(&ctrl->pidZ,zPositionActual, true);
float yawError;
pidSetDesired(&ctrl->pidYaw, eulerYawDesired);
yawError = eulerYawDesired - eulerYawActual;
if(yawError > 180.0) //Ensures Yaw error stays between -180 and 180 degrees
yawError -= 360.0;
else if(yawError < -180.0)
yawError += 360.0;
pidSetError(&ctrl->pidYaw, yawError);
*yawControlOutput = pidUpdateYaw(&ctrl->pidYaw, eulerYawActual, true); //originally false
}
</pre>
</code>
</blockquote>
:3. In each Callback, calculate the Controller outputs, assigned to pointer values<code>*rollControlOutput</code>, <code>*pitchControlOutput</code>, etc... (code in ''eris_vrpn.cpp''):
<blockquote>
<code>
<pre>
xError1 = xPositionDesired1 - xPosition1;
yError1 = yPositionDesired1 - yPosition1; //Calculates error externally
controllerSetXYError(&pidCtrl1, xError1, yError1);
controllerCorrectAttitudePID(&pidCtrl1, t.pos[0], t.pos[1], zPosition1, correctedYaw1,
xPositionDesired1, yPositionDesired1, zPositionDesired1,
yawDesired1, &rollControlOutput1, &pitchControlOutput1,
&yawControlOutput1, &thrustControlOutput1);
</pre>
</code>
</blockquote>
::'''Note:''' We calculate error externally for X and Y because certain swarm controllers need special setpoint modifiers (this way we can switch modes without effecting the default setpoint):
::'''Example:''' Follow Hand Mode Error (Crazyflie1 will have setpoint -0.5 m lower in X and +0.5 m higher in Y than your hand trackable):
<blockquote>
<code>
<pre>
...
xError1 = (xPositionHand - 0.5) - xPosition1;
yError1 = (yPositionHand + 0.5) - yPosition1;
controllerSetXYError(&pidCtrl1, xError1, yError1);
...
</pre>
</code>
</blockquote>
:4. Repeat for each set of new location data...until Program END.
----
<center> '''Main Directory''' </center>
<center> [[Crazyflie Swarm|Crazyflie Swarm Home]] | [[PC Client Software]] | [[USB Radio]] | [[Firmware]] | [[FAQ]] </center>
<center> '''Modifications Directory''' </center>
<center> [[Controller]] | [[Logging]] | [[Keyboard Commands]] | [[USB Radio#Changing Radio Channel|Changing Radio Channel]] | [[Flight Modes]] | [[Callbacks]] | [[Adding a Crazyflie]] | [[Firmware]] </center>
ca838e1358b4d3a7ec439457c0424ef221297ac6
133
132
2016-07-21T19:32:04Z
Jnoronha
3
/* PC Client */ added sending calculated setpoints over the radio code
wikitext
text/x-wiki
The Crazyflie platform is completely customizable when it comes to the control design. As long as the controller can be written in C or C++, we can implement it in the Platform. This applies to both the controllers run on the PC Client and the controllers run on the Firmware of the Crazyflie. Originally the only controllers in the Platform were Firmware PID's that controlled the angular position and rates of the Crazyflie for hand flight. The original controller layout can be seen here [[#Original PID Controllers (Angular Rotation)|Original PID's]].
Below you will find documentation on the different types of Controllers that have been applied to the platform, organized by their location in the Platform.
== Firmware ==
=== Original PID Controllers (Angular Rotation) ===
Directly on the Crazyflie Firmware there are 5 PID controllers as seen here:
[[Image:FirmwareOnlyPIDArchitecture.png|500px]]
The Pitch and Roll angular position PID's receive constant setpoints from some outside source (gamepad controller or automated controller). The outputs of those angular position controllers is then fed into the angular rate controllers as shown. This final output is then fed into the Motor Command block which converts the angular rate setpoints into motor commands.
----
===State Estimator (Not Implemented Yet)===
('''***NOT YET IMPLEMENTED***''')
Bitcraze is currently working on adding a state estimator onto the Firmware to handle control calculations instead of the PID.
The code is in place but the controller is not yet used as of '''7/13/16'''.
== PC Client ==
=== Client PID Controllers (Position and Yaw) ===
The first controller implemented on the Client were 4 PID controllers used to stabilize the Crazyflie's position in X, Y, and Z, and angular position in Yaw respectively. These PID's feed directly into the Firmware PID's as seen here:
[[Image:CompletePIDArchitectureFigure.png|500px]]
The controllers inside the red box are the original PID controllers located on the Firmware as shown above in the [[#Original PID Controllers (Angular Rotation)|Original PID's]].
====Initialize the PID's====
:1. To start we create a struct with all the necessary variables (code from ''pid.h''):
<blockquote>
<code>
<pre>
typedef struct
{
float desired; //< set point
float error; //< error
float prevError; //< previous error
float integ; //< integral
float deriv; //< derivative
float kp; //< proportional gain
float ki; //< integral gain
float kd; //< derivative gain
float outP; //< proportional output (debugging)
float outI; //< integral output (debugging)
float outD; //< derivative output (debugging)
float iLimit; //< integral limit
float iLimitLow; //< integral limit
float dt; //< delta-time dt
float angularLimit; //sets limit for how far Crazyflie can tip, to prevent flipping
float angularLimitLow; //^
float thrustLimit; //Sets upper limit for Thrust Output (60000?) **?
float thrustLimitLow; //Sets lower limit for thrust Output (10001)
} PidObject;
</pre>
</code>
</blockquote>
:2. To simplify scaling up the code to multiple Crazyflies, we will create a <code> ControllerObject </code> that contains multiple PID structs as shown (code in ''controller.h''):
<blockquote>
<code>
<pre>
typedef struct
{
PidObject pidRoll;
PidObject pidPitch;
PidObject pidYaw;
PidObject pidX;
PidObject pidY;
PidObject pidZ;
bool isInit;
} ControllerObject;
</pre>
</code>
</blockquote>
:3. Then we initialize the Objects to 0 at the start of each run (code in ''eris_vrpn.cpp''):
<blockquote>
<code>
<pre>
ControllerObject pidCtrl1 = { 0 }; // init all fields to zero
ControllerObject pidCtrl2 = { 0 }; // init all fields to zero
ControllerObject pidCtrl3 = { 0 }; // init all fields to zero
ControllerObject pidCtrl4 = { 0 }; // init all fields to zero
</pre>
</code>
</blockquote>
:4. Then populate the PidObjects with the desired parameters (code in ''pid.c''):
<blockquote>
<code>
<pre>
void pidInit(PidObject* pid, const float desired, const float kp,
const float ki, const float kd, const float dt)
{
pid->error = 0;
pid->prevError = 0;
pid->integ = 0;
pid->deriv = 0;
pid->desired = desired;
pid->kp = kp;
pid->ki = ki;
pid->kd = kd;
pid->iLimit = DEFAULT_PID_INTEGRATION_LIMIT;
pid->iLimitLow = -DEFAULT_PID_INTEGRATION_LIMIT;
pid->angularLimit = DEFAULT_PID_ANGLE_OUTPUT;
pid->angularLimitLow = -DEFAULT_PID_ANGLE_OUTPUT;
pid->thrustLimit = DEFAULT_PID_HIGH_THRUST_LIMIT;
pid->thrustLimitLow = DEFAULT_PID_LOW_THRUST_LIMIT;
pid->dt = dt;
}
</pre>
</code>
</blockquote>
Using the above function for each of the <code>PidObjects</code> inside of the <code>ControllerObject</code> below (code in ''controller.c''):
<blockquote>
<code>
<pre>
void controllerInit( ControllerObject * ctrl )
{
if(ctrl->isInit)
return;
pidInit(&ctrl->pidY, 0, PID_Y_KP, PID_Y_KI, PID_Y_KD, CAMERA_UPDATE_DT); //for Roll PID
pidInit(&ctrl->pidX, 0, PID_X_KP, PID_X_KI, PID_X_KD, CAMERA_UPDATE_DT); //for Pitch PID
pidInit(&ctrl->pidYaw, 0, PID_YAW_KP, PID_YAW_KI, PID_YAW_KD, CAMERA_UPDATE_DT);
pidInit(&ctrl->pidZ, 0, PID_Z_KP, PID_Z_KI, PID_Z_KD, CAMERA_UPDATE_DT);
pidSetIntegralLimit(&ctrl->pidY, PID_Y_INTEGRATION_LIMIT);
pidSetIntegralLimit(&ctrl->pidX, PID_X_INTEGRATION_LIMIT);
pidSetIntegralLimit(&ctrl->pidYaw, PID_YAW_INTEGRATION_LIMIT);
pidSetIntegralLimit(&ctrl->pidZ, PID_Z_INTEGRATION_LIMIT);
ctrl->isInit = true;
}
</pre>
</code>
</blockquote>
'''Note:''' If we have multiple Crazyflies we need a <code>ControllerObject</code> for each Crazyflie (code in ''eris_vrpn.cpp'')
<blockquote>
<code>
<pre>
controllerResetAllPID( &pidCtrl1 );
controllerInit( &pidCtrl1 );
#endif
#if NUM_QUADS >= 2
controllerResetAllPID( &pidCtrl2 );
controllerInit( &pidCtrl2 );
#endif
#if NUM_QUADS >=3
controllerResetAllPID( &pidCtrl3 );
controllerInit( &pidCtrl3 );
#endif
#if NUM_QUADS >=4
controllerResetAllPID( &pidCtrl4 );
controllerInit( &pidCtrl4 );
#endif
</pre>
</code>
</blockquote>
Now the initialization of the Controllers is complete.
====Calculating the PID's====
:1. Each loop we want to calculate the PID output (code in ''pid.c''):
<blockquote>
<code>
<pre>
float pidUpdateAngle(PidObject* pid, const float measured, const bool updateError) //**USED FOR ATTITUDE CONTROL
{
float output;
if(updateError)
{
pid->error = pid->desired - measured; //Calculates current error
}
pid->integ += pid->error * pid->dt; //Calculates integral term
if(pid->integ > pid->iLimit) //Checks that the integral term stays below the integral limit (anti-windup)
{
pid->integ = pid->iLimit;
}
else if(pid->integ < pid->iLimitLow)
{
pid->integ = pid->iLimitLow;
}
pid->deriv = (pid->error - pid->prevError) / pid->dt; //Calculates derivative term
pid->outP = pid->kp* pid->error;
pid->outI = pid->ki * pid->integ;
pid->outD = pid->kd * pid->deriv;
output = pid->outP + pid->outI + pid->outD; //Adds up all 3 calculated terms for output
if(output > pid->angularLimit) //Limits amount Crazyflie can tip
{
output = pid->angularLimit;
}
if(output < pid->angularLimitLow) //Limits amount Crazyflie can tip
{
output = pid->angularLimitLow;
}
pid->prevError = pid->error; //Stores the current error for next loop
return output;
}
</pre>
</code>
</blockquote>
::'''Note:''' There are 3 different versions of this Function (for Angle, Thrust, and Yaw) since each has different output limits.
:2. Using the function above, combine all PID calculations into one function (code in ''controller.c''):
<blockquote>
<code>
<pre>
void controllerCorrectAttitudePID(ControllerObject * ctrl,
float xPositionActual, float yPositionActual, float zPositionActual, float eulerYawActual, float xPositionDesired, float yPositionDesired,
float zPositionDesired, float eulerYawDesired, float* rollControlOutput, float* pitchControlOutput, float* yawControlOutput, float* thrustControlOutput)
{
pidSetDesired(&ctrl->pidX, xPositionDesired);
*pitchControlOutput = pidUpdateAngle(&ctrl->pidX, xPositionActual, false); //Originally true
pidSetDesired(&ctrl->pidY, yPositionDesired);
*rollControlOutput = pidUpdateAngle(&ctrl->pidY, yPositionActual, false); //Originally true
pidSetDesired(&ctrl->pidZ, zPositionDesired);
*thrustControlOutput = pidUpdateThrust(&ctrl->pidZ,zPositionActual, true);
float yawError;
pidSetDesired(&ctrl->pidYaw, eulerYawDesired);
yawError = eulerYawDesired - eulerYawActual;
if(yawError > 180.0) //Ensures Yaw error stays between -180 and 180 degrees
yawError -= 360.0;
else if(yawError < -180.0)
yawError += 360.0;
pidSetError(&ctrl->pidYaw, yawError);
*yawControlOutput = pidUpdateYaw(&ctrl->pidYaw, eulerYawActual, true); //originally false
}
</pre>
</code>
</blockquote>
:3. In each Callback, calculate the Controller outputs, assigned to pointer values <code>*rollControlOutput</code>, <code>*pitchControlOutput</code>, etc... (code in ''eris_vrpn.cpp''):
<blockquote>
<code>
<pre>
xError1 = xPositionDesired1 - xPosition1;
yError1 = yPositionDesired1 - yPosition1; //Calculates error externally
controllerSetXYError(&pidCtrl1, xError1, yError1);
controllerCorrectAttitudePID(&pidCtrl1, t.pos[0], t.pos[1], zPosition1, correctedYaw1,
xPositionDesired1, yPositionDesired1, zPositionDesired1,
yawDesired1, &rollControlOutput1, &pitchControlOutput1,
&yawControlOutput1, &thrustControlOutput1);
</pre>
</code>
</blockquote>
::'''Note 1:''' We calculate error externally for X and Y because certain swarm controllers need special setpoint modifiers (this way we can switch modes without effecting the default setpoint):
::'''Note 2:''' Swap out the Controller - all we need to do is create a similar function and replace ''controllerCorrectAttitudePID'' above
::'''Example:''' Follow Hand Mode Error (Crazyflie1 will have setpoint -0.5 m lower in X and +0.5 m higher in Y than your hand trackable):
<blockquote>
<code>
<pre>
...
xError1 = (xPositionHand - 0.5) - xPosition1;
yError1 = (yPositionHand + 0.5) - yPosition1;
controllerSetXYError(&pidCtrl1, xError1, yError1);
...
</pre>
</code>
</blockquote>
:4. Send Calculated Control Outputs to the Crazyflie via the Radio (code found in ''simple.cpp''):
<blockquote>
<code>
<pre>
RunCrazyflie(crRadio2, cflieCopter3, rollControlOutput3, pitchControlOutput3, yawControlOutput3, thrustControlOutput3);
</pre>
</code>
</blockquote>
::Where the ''RunCrazyflie'' function looks like this (code in ''simple.cpp''):
<blockquote>
<code>
<pre>
int RunCrazyflie(CCrazyRadio *crRadio, CCrazyflie *cflieCopter, float rollControl, float pitchControl, float yawControl, float thrustControl) {
//Timing Index Variables (**FOR TESTING ROUTINES**)
int i = 0;
while(cflieCopter->cycle()) {
//If Crazyflie is vertical kill motors, Crash Imminent
if(cflieCopter->roll() > 90){
cflieCopter->setThrust(10000);
}
else if(cflieCopter->roll() < -90){
cflieCopter->setThrust(10000);
}
else if(cflieCopter->pitch() > 90){
cflieCopter->setThrust(10000);
}
else if(cflieCopter->pitch() < -90){
cflieCopter->setThrust(10000);
}
//Otherwise Send Setpoints
else if(i < 1){ //i < 200000
cflieCopter->setThrust(thrustControl);
cflieCopter->setRoll(rollControl);
cflieCopter->setPitch(pitchControl);
cflieCopter->setYaw(-yawControl); //******SET TO NEGATIVE FOR CAMERA SYSTEM YAW BEING REVERSED!!!!****
i++;
}
else{
break;
}
}
return 0;
}
</pre>
</code>
</blockquote>
::'''IMPORTANT:''' This function contains the function <code>cflieCopter->cycle()</code> which is CRITICAL to maintaining communications with the Crazyflie. The ''cycle'' function initiates communications, sends setpoints, and must be called frequently otherwise the communications will timeout and the Crazyflie will stop as a precaution.
:5. Repeat steps 3 through 5 for each set of new location data...until Program END.
===Swapping Client Controller Type===
With the Swarm Platform we can plug any controller (that can be coded in C or C++) into the Client to control the Crazyflies.
In steps 1, 2, and 3 of the [[#Calculating the PID's|Calculating the PID's]] section, you can see the whole process of how we calculate the control output. To replace the PID with a different controller we can follow those steps but with our new controller. So as a general idea of the process we have:
('''Note:''' This depends heavily on how your controller works, this is generalized for a single input single output controller)
#Implement the New Controller Output Calculation in C as a function
#Create multiple instances of this controller calculation function (for each Degree of Freedom (DOF) you need to control) and combine them into a function to calculate all controllers with 1 function call ('''Note:''' This step is for ease of code use, NOT Required)
#In each Callback, call the function to Calculate the Controller output.
----
<center> '''Main Directory''' </center>
<center> [[Crazyflie Swarm|Crazyflie Swarm Home]] | [[PC Client Software]] | [[USB Radio]] | [[Firmware]] | [[FAQ]] </center>
<center> '''Modifications Directory''' </center>
<center> [[Controller]] | [[Logging]] | [[Keyboard Commands]] | [[USB Radio#Changing Radio Channel|Changing Radio Channel]] | [[Flight Modes]] | [[Callbacks]] | [[Adding a Crazyflie]] | [[Firmware]] </center>
7d4ecb606d5ddf4995f324e07dd6ba595fb83190
Crazyflie Swarm
0
2
126
97
2016-07-21T18:25:11Z
Jnoronha
3
Added Future Project Ideas Section
wikitext
text/x-wiki
The Crazyflie Swarm is a Networked Control platform designed for students to learn more about control and for researchers that wish to apply their research in practice. Platform development was started during the Summer of 2015 and continues to this day.
Here you will find descriptions on how the platform works, how you can use it, and how you can get involved in developing the platform further!
== Frequently Asked Questions ==
For help with common problems and troubleshooting please see the [[FAQ]].
== Background ==
The Crazyflie Swarm platform is based off of the ''Crazyflie'' Nano-quadcopter produced and maintained by [https://www.bitcraze.io/ Bitcraze]. The ''Crazyflie'' is completely open-source so we are able to look at and modify any part of the code and customize it to our needs.
=== Major Platform Components: ===
[[Image: High_Level_Figure_(Single_Radio_Single_Crazyflie_NO_NUMBERS_CROPPED).jpg|thumb|right|A high level overview of the Crazyflie Platform]]
*[[PC Client Software]]
*[[Firmware]]
*[[USB Radio]]
== Modifying the Platform ==
*[[Controller]]
*[[Logging]]
*[[Keyboard Commands]]
*[[USB Radio#Changing Radio Channel|Changing Radio Channel]]
*[[Flight Modes]]
*[[Callbacks]]
*[[Adding a Crazyflie]]
*[[:Firmware]]
==Future Project Ideas==
The whole concept of this Platform is to constantly expand its capabilities. If you are interested in developing this platform further [[Future Project Ideas|here are some ideas]] to get you started!
*Migrating Swarm Client PID's to Firmware
*Adding Parameter Support to Swarm Client
*Threading Each USB Radio to speed up Computation
*Crazyflie Model Development and Verification
*Developing New Controllers for the Crazyflie (pending Model Development)
== [https://wiki.bitcraze.io/ Bitcraze Wiki] ==
Bitcraze maintains their own wiki on the many Crazyflie systems. If you can't find what you are looking for here, chances are they will have something to help.
655ebf3fd5e434f919afe7e3b4316a0d2977e3f9
127
126
2016-07-21T18:25:34Z
Jnoronha
3
removed a carriage return
wikitext
text/x-wiki
The Crazyflie Swarm is a Networked Control platform designed for students to learn more about control and for researchers that wish to apply their research in practice. Platform development was started during the Summer of 2015 and continues to this day.
Here you will find descriptions on how the platform works, how you can use it, and how you can get involved in developing the platform further!
== Frequently Asked Questions ==
For help with common problems and troubleshooting please see the [[FAQ]].
== Background ==
The Crazyflie Swarm platform is based off of the ''Crazyflie'' Nano-quadcopter produced and maintained by [https://www.bitcraze.io/ Bitcraze]. The ''Crazyflie'' is completely open-source so we are able to look at and modify any part of the code and customize it to our needs.
=== Major Platform Components: ===
[[Image: High_Level_Figure_(Single_Radio_Single_Crazyflie_NO_NUMBERS_CROPPED).jpg|thumb|right|A high level overview of the Crazyflie Platform]]
*[[PC Client Software]]
*[[Firmware]]
*[[USB Radio]]
== Modifying the Platform ==
*[[Controller]]
*[[Logging]]
*[[Keyboard Commands]]
*[[USB Radio#Changing Radio Channel|Changing Radio Channel]]
*[[Flight Modes]]
*[[Callbacks]]
*[[Adding a Crazyflie]]
*[[:Firmware]]
==Future Project Ideas==
The whole concept of this Platform is to constantly expand its capabilities. If you are interested in developing this platform further [[Future Project Ideas|here are some ideas]] to get you started!
*Migrating Swarm Client PID's to Firmware
*Adding Parameter Support to Swarm Client
*Threading Each USB Radio to speed up Computation
*Crazyflie Model Development and Verification
*Developing New Controllers for the Crazyflie (pending Model Development)
== [https://wiki.bitcraze.io/ Bitcraze Wiki] ==
Bitcraze maintains their own wiki on the many Crazyflie systems. If you can't find what you are looking for here, chances are they will have something to help.
4b353616023e89cf446bdc9ed5bf6af0288aa2c3
128
127
2016-07-21T18:39:12Z
Jnoronha
3
/* Future Project Ideas */ added link to more detailed project description
wikitext
text/x-wiki
The Crazyflie Swarm is a Networked Control platform designed for students to learn more about control and for researchers that wish to apply their research in practice. Platform development was started during the Summer of 2015 and continues to this day.
Here you will find descriptions on how the platform works, how you can use it, and how you can get involved in developing the platform further!
== Frequently Asked Questions ==
For help with common problems and troubleshooting please see the [[FAQ]].
== Background ==
The Crazyflie Swarm platform is based off of the ''Crazyflie'' Nano-quadcopter produced and maintained by [https://www.bitcraze.io/ Bitcraze]. The ''Crazyflie'' is completely open-source so we are able to look at and modify any part of the code and customize it to our needs.
=== Major Platform Components: ===
[[Image: High_Level_Figure_(Single_Radio_Single_Crazyflie_NO_NUMBERS_CROPPED).jpg|thumb|right|A high level overview of the Crazyflie Platform]]
*[[PC Client Software]]
*[[Firmware]]
*[[USB Radio]]
== Modifying the Platform ==
*[[Controller]]
*[[Logging]]
*[[Keyboard Commands]]
*[[USB Radio#Changing Radio Channel|Changing Radio Channel]]
*[[Flight Modes]]
*[[Callbacks]]
*[[Adding a Crazyflie]]
*[[:Firmware]]
==Future Project Ideas==
The whole concept of this Platform is to constantly expand its capabilities. If you are interested in developing this platform further here are some ideas to get you started! Additional details on any of these ideas can be found on the [[Future Project Ideas]] page.
*Migrating Swarm Client PID's to Firmware
*Adding Parameter Support to Swarm Client
*Threading Each USB Radio to speed up Computation
*Crazyflie Model Development and Verification
*Developing New Controllers for the Crazyflie (pending Model Development)
== [https://wiki.bitcraze.io/ Bitcraze Wiki] ==
Bitcraze maintains their own wiki on the many Crazyflie systems. If you can't find what you are looking for here, chances are they will have something to help.
12d746527b02a1f37c5636773419960073727c1c
129
128
2016-07-21T18:48:45Z
Jnoronha
3
/* Future Project Ideas */ added a few more ideas
wikitext
text/x-wiki
The Crazyflie Swarm is a Networked Control platform designed for students to learn more about control and for researchers that wish to apply their research in practice. Platform development was started during the Summer of 2015 and continues to this day.
Here you will find descriptions on how the platform works, how you can use it, and how you can get involved in developing the platform further!
== Frequently Asked Questions ==
For help with common problems and troubleshooting please see the [[FAQ]].
== Background ==
The Crazyflie Swarm platform is based off of the ''Crazyflie'' Nano-quadcopter produced and maintained by [https://www.bitcraze.io/ Bitcraze]. The ''Crazyflie'' is completely open-source so we are able to look at and modify any part of the code and customize it to our needs.
=== Major Platform Components: ===
[[Image: High_Level_Figure_(Single_Radio_Single_Crazyflie_NO_NUMBERS_CROPPED).jpg|thumb|right|A high level overview of the Crazyflie Platform]]
*[[PC Client Software]]
*[[Firmware]]
*[[USB Radio]]
== Modifying the Platform ==
*[[Controller]]
*[[Logging]]
*[[Keyboard Commands]]
*[[USB Radio#Changing Radio Channel|Changing Radio Channel]]
*[[Flight Modes]]
*[[Callbacks]]
*[[Adding a Crazyflie]]
*[[:Firmware]]
==Future Project Ideas==
The whole concept of this Platform is to constantly expand its capabilities. If you are interested in developing this platform further here are some ideas to get you started! Additional details on any of these ideas can be found on the [[Future Project Ideas]] page.
*Migrating Swarm Client PID's to Firmware
*Adding Parameter Support to Swarm Client
*Threading Each USB Radio to speed up Computation
*Crazyflie Model Development and Verification
*Developing New Controllers for the Crazyflie (pending Model Development)
*Develop Communications Network Between Crazyflies
*Trilateration Position Estimation using a Swarm
== [https://wiki.bitcraze.io/ Bitcraze Wiki] ==
Bitcraze maintains their own wiki on the many Crazyflie systems. If you can't find what you are looking for here, chances are they will have something to help.
f4a85985645b36236cd6da453966219729392ac6
130
129
2016-07-21T18:50:38Z
Jnoronha
3
/* Future Project Ideas */ added pid tuning idea
wikitext
text/x-wiki
The Crazyflie Swarm is a Networked Control platform designed for students to learn more about control and for researchers that wish to apply their research in practice. Platform development was started during the Summer of 2015 and continues to this day.
Here you will find descriptions on how the platform works, how you can use it, and how you can get involved in developing the platform further!
== Frequently Asked Questions ==
For help with common problems and troubleshooting please see the [[FAQ]].
== Background ==
The Crazyflie Swarm platform is based off of the ''Crazyflie'' Nano-quadcopter produced and maintained by [https://www.bitcraze.io/ Bitcraze]. The ''Crazyflie'' is completely open-source so we are able to look at and modify any part of the code and customize it to our needs.
=== Major Platform Components: ===
[[Image: High_Level_Figure_(Single_Radio_Single_Crazyflie_NO_NUMBERS_CROPPED).jpg|thumb|right|A high level overview of the Crazyflie Platform]]
*[[PC Client Software]]
*[[Firmware]]
*[[USB Radio]]
== Modifying the Platform ==
*[[Controller]]
*[[Logging]]
*[[Keyboard Commands]]
*[[USB Radio#Changing Radio Channel|Changing Radio Channel]]
*[[Flight Modes]]
*[[Callbacks]]
*[[Adding a Crazyflie]]
*[[:Firmware]]
==Future Project Ideas==
The whole concept of this Platform is to constantly expand its capabilities. If you are interested in developing this platform further here are some ideas to get you started! Additional details on any of these ideas can be found on the [[Future Project Ideas]] page.
*Migrating Swarm Client PID's to Firmware
*Tuning X, Y, and Z Location PID's for Faster Response
*Adding Parameter Support to Swarm Client
*Threading Each USB Radio to speed up Computation
*Crazyflie Model Development and Verification
*Developing New Controllers for the Crazyflie (pending Model Development)
*Develop Communications Network Between Crazyflies
*Trilateration Position Estimation using a Swarm
== [https://wiki.bitcraze.io/ Bitcraze Wiki] ==
Bitcraze maintains their own wiki on the many Crazyflie systems. If you can't find what you are looking for here, chances are they will have something to help.
41267c5d3351c9d7a8a79454a4c93eb9717e929c
Keyboard Commands
0
41
137
2016-07-26T16:44:47Z
Jnoronha
3
completed Keyboard Input code
wikitext
text/x-wiki
Keyboard commands give the user the ability to modify variables during a flight test. The actions each key performs is completely customizable and can trigger anything from just adjusting a PID constant, to executing complex functions.
==Reading the Keyboard Input==
We use the <code>select()</code> function for a non-blocking method to read the keyboard input from the <code>STDIN</code> file descriptor in linux. The function below is what we currently use to read the keyboard. (The function was provided by Dr. Phillip Jones):
:1. First we need to establish the base functions that we will use to read the key input (code found in ''vrpn.cpp''):
<blockquote>
<code>
<pre>
//////////////////////////////////////////////////
// kbhit //
// Descption: used select to do a non blocking //
// read of stdin. //
// //
//////////////////////////////////////////////////
int kbhit()
{
struct timeval tv;
fd_set fds;
tv.tv_sec = 0;
tv.tv_usec = 0;
FD_ZERO(&fds);
FD_SET(STDIN_FILENO, &fds); //STDIN_FILENO is 0
select(STDIN_FILENO+1, &fds, NULL, NULL, &tv);
return FD_ISSET(STDIN_FILENO, &fds);
}
</pre>
</code>
</blockquote>
::Then we can make it non-blocking code with the following:
<blockquote>
<code>
<pre>
//////////////////////////////////////////////////
// nonblock //
// Descption: Turn off connoical mode so the //
// user does not need to hit enter after //
// pressing a key //
// //
//////////////////////////////////////////////////
void nonblock(int state)
{
struct termios ttystate;
//get the terminal state
tcgetattr(STDIN_FILENO, &ttystate);
if (state==1)
{
//turn off canonical mode
ttystate.c_lflag &= ~ICANON;
//minimum of number input read.
ttystate.c_cc[VMIN] = 1;
}
else if (state==0)
{
//turn on canonical mode
ttystate.c_lflag |= ICANON;
}
//set the terminal attributes.
tcsetattr(STDIN_FILENO, TCSANOW, &ttystate);
}
</pre>
</code>
</blockquote>
:2. Reading the Keypress (code in ''vrpn.cpp''):
<blockquote>
<code>
<pre>
nonblock(1);
usleep(1);
i = kbhit(); //keyboard hit (state change)
if (i!=0) //If state has changed, read and record key value
{
keystroke_now = fgetc(stdin);
if (keystroke_now == 'q')
i=1;
else{
i=0;
}
} //END IF
readKeyboard(); //Uses key value input to trigger actions
</pre>
</code>
</blockquote>
::All this code is doing is checking the <code>STDIN</code> file descriptor for a state change, if it has then read that change and record the key value that was pressed.
:3. Using the Key value to trigger actions (code in ''vrpn.cpp''):
<blockquote>
<code>
<pre>
void readKeyboard()
{
//========Reads Keystrokes from Keyboard==========
nonblock(1);
if (keystroke_now != keystroke_prev) { //If the keyvalue has changed (Debouncing safety)
/*
if (keystroke_now == 'w') {
yPositionDesired1 -= 0.2;
cout << "New Y Setpoint: " << yPositionDesired1 << endl;
} else if (keystroke_now == 's') {
yPositionDesired1 += 0.2;
cout << "New Y Setpoint: " << yPositionDesired1 << endl;
} else if (keystroke_now == 'a') {
xPositionDesired1 -= 0.2;
cout << "New X Setpoint: " << xPositionDesired1 << endl;
} else if (keystroke_now == 'd') {
xPositionDesired1 += 0.2;
cout << "New X Setpoint: " << xPositionDesired1 << endl;
} else if (keystroke_now == 'r') {
zPositionDesired1 += 0.2;
cout << "New Z Setpoint: " << zPositionDesired1 << endl;
} else if (keystroke_now == 'f') {
zPositionDesired1 -= 0.2;
cout << "New Z Setpoint: " << zPositionDesired1 << endl;
}
*/ //Commented out above inputs
if (keystroke_now == '1') {
yawDesired1 += 45.0;
cout << "New Yaw Setpoint: " << yawDesired1 << endl;
} else if (keystroke_now == '2') {
yawDesired1 -= 45.0;
cout << "New Yaw Setpoint: " << yawDesired1 << endl;
}
else if (keystroke_now == 'k') {
cflieCopter1->m_enumFlightMode = GROUNDED_MODE;
if(cflieCopter2){
cflieCopter2->m_enumFlightMode = GROUNDED_MODE;}
if(cflieCopter3){
cflieCopter3->m_enumFlightMode = GROUNDED_MODE;}
if(cflieCopter4){
cflieCopter4->m_enumFlightMode = GROUNDED_MODE;}
} else if (keystroke_now == 'e') {
cflieCopter1->m_enumFlightMode = LANDING_MODE;
if(cflieCopter2){
cflieCopter2->m_enumFlightMode = LANDING_MODE;}
if(cflieCopter3){
cflieCopter3->m_enumFlightMode = LANDING_MODE;}
if(cflieCopter4){
cflieCopter4->m_enumFlightMode = LANDING_MODE;}
handMode = 0;
// landingMode ^= 1;
// mirrorMode = 0;
cout << "Landing Mode Enabled" << endl;
} else if (keystroke_now == 'm') {
cflieCopter1->m_enumFlightMode = MIRROR_MODE;
if(cflieCopter2){
cflieCopter2->m_enumFlightMode = MIRROR_MODE;}
if(cflieCopter3){
cflieCopter3->m_enumFlightMode = MIRROR_MODE;}
if(cflieCopter4){
cflieCopter4->m_enumFlightMode = MIRROR_MODE;}
// mirrorMode ^= 1;
cout << "Mirror Mode Enabled" << endl;
} else if (keystroke_now == 'h') {
handMode = 1;
cout << "Hand Mode Enabled" << endl;
} else if (keystroke_now == 't') {
cflieCopter1->m_enumFlightMode = TAKEOFF_MODE;
// takeOff1 = 1;
takeOffTime1 = cflieCopter1->currentTime() - initTime1;
}
else if (keystroke_now == 'y') {
cflieCopter2->m_enumFlightMode = TAKEOFF_MODE;
// takeOff2 = 1;
takeOffTime2 = cflieCopter2->currentTime() - initTime2;
}
else if (keystroke_now == 'u') {
cflieCopter3->m_enumFlightMode = TAKEOFF_MODE;
// takeOff3 = 1;
takeOffTime3 = cflieCopter3->currentTime() - initTime3;
}
else if (keystroke_now == 'i') {
cflieCopter4->m_enumFlightMode = TAKEOFF_MODE;
// takeOff4 = 1;
takeOffTime4 = cflieCopter4->currentTime() - initTime4;
}
// else if (keystroke_now == '`') {
// tcp_server_ON ^= 1;
// } else if (keystroke_now == '1') {
// tcp_client_ON ^= 1;
// }
// else if (keystroke_now == 'o') {
// flap = 1;
// }
// else if (keystroke_now == 'l') {
// flap = 0;
// }
keystroke_prev = keystroke_now;
}
nonblock(0);
}//END readKeyboard()
</pre>
</code>
</blockquote>
::This is just a bunch of 'if' checks that activate if a certain key has been pressed.
::*So we can see that the first 8 options just simply add or subtract a constant value to a variable in the code whenever that key is pressed.
::*The options after that are what trigger different [[:Flight States]], telling the Crazyflie to do things like ''Take-Off'', or to ''Fly in Formation'', or to ''Land''. These are more complex functions and can change the behavior of the entire swarm! See the [[:Flight States]] page for more information on this.
----
<center> '''Main Directory''' </center>
<center> [[Crazyflie Swarm|Crazyflie Swarm Home]] | [[PC Client Software]] | [[USB Radio]] | [[Firmware]] | [[FAQ]] </center>
<center> '''Modifications Directory''' </center>
<center> [[Controller]] | [[Logging]] | [[Keyboard Commands]] | [[USB Radio#Changing Radio Channel|Changing Radio Channel]] | [[Flight Modes]] | [[Callbacks]] | [[Adding a Crazyflie]] | [[Firmware]] </center>
d2d522e6ba1f3e4d4772b5fc48a5858a31a9675d
138
137
2016-07-26T16:47:31Z
Jnoronha
3
Added keyboard input flow chart
wikitext
text/x-wiki
Keyboard commands give the user the ability to modify variables during a flight test. The actions each key performs is completely customizable and can trigger anything from just adjusting a PID constant, to executing complex functions.
To get the basic idea of how the function works, here is a flow chart of the process and an example trigger:
[[Image:Keyboard_Input.png]]
==Reading the Keyboard Input==
We use the <code>select()</code> function for a non-blocking method to read the keyboard input from the <code>STDIN</code> file descriptor in linux. The function below is what we currently use to read the keyboard. (The function was provided by Dr. Phillip Jones):
:1. First we need to establish the base functions that we will use to read the key input (code found in ''vrpn.cpp''):
<blockquote>
<code>
<pre>
//////////////////////////////////////////////////
// kbhit //
// Descption: used select to do a non blocking //
// read of stdin. //
// //
//////////////////////////////////////////////////
int kbhit()
{
struct timeval tv;
fd_set fds;
tv.tv_sec = 0;
tv.tv_usec = 0;
FD_ZERO(&fds);
FD_SET(STDIN_FILENO, &fds); //STDIN_FILENO is 0
select(STDIN_FILENO+1, &fds, NULL, NULL, &tv);
return FD_ISSET(STDIN_FILENO, &fds);
}
</pre>
</code>
</blockquote>
::Then we can make it non-blocking code with the following:
<blockquote>
<code>
<pre>
//////////////////////////////////////////////////
// nonblock //
// Descption: Turn off connoical mode so the //
// user does not need to hit enter after //
// pressing a key //
// //
//////////////////////////////////////////////////
void nonblock(int state)
{
struct termios ttystate;
//get the terminal state
tcgetattr(STDIN_FILENO, &ttystate);
if (state==1)
{
//turn off canonical mode
ttystate.c_lflag &= ~ICANON;
//minimum of number input read.
ttystate.c_cc[VMIN] = 1;
}
else if (state==0)
{
//turn on canonical mode
ttystate.c_lflag |= ICANON;
}
//set the terminal attributes.
tcsetattr(STDIN_FILENO, TCSANOW, &ttystate);
}
</pre>
</code>
</blockquote>
:2. Reading the Keypress (code in ''vrpn.cpp''):
<blockquote>
<code>
<pre>
nonblock(1);
usleep(1);
i = kbhit(); //keyboard hit (state change)
if (i!=0) //If state has changed, read and record key value
{
keystroke_now = fgetc(stdin);
if (keystroke_now == 'q')
i=1;
else{
i=0;
}
} //END IF
readKeyboard(); //Uses key value input to trigger actions
</pre>
</code>
</blockquote>
::All this code is doing is checking the <code>STDIN</code> file descriptor for a state change, if it has then read that change and record the key value that was pressed.
:3. Using the Key value to trigger actions (code in ''vrpn.cpp''):
<blockquote>
<code>
<pre>
void readKeyboard()
{
//========Reads Keystrokes from Keyboard==========
nonblock(1);
if (keystroke_now != keystroke_prev) { //If the keyvalue has changed (Debouncing safety)
/*
if (keystroke_now == 'w') {
yPositionDesired1 -= 0.2;
cout << "New Y Setpoint: " << yPositionDesired1 << endl;
} else if (keystroke_now == 's') {
yPositionDesired1 += 0.2;
cout << "New Y Setpoint: " << yPositionDesired1 << endl;
} else if (keystroke_now == 'a') {
xPositionDesired1 -= 0.2;
cout << "New X Setpoint: " << xPositionDesired1 << endl;
} else if (keystroke_now == 'd') {
xPositionDesired1 += 0.2;
cout << "New X Setpoint: " << xPositionDesired1 << endl;
} else if (keystroke_now == 'r') {
zPositionDesired1 += 0.2;
cout << "New Z Setpoint: " << zPositionDesired1 << endl;
} else if (keystroke_now == 'f') {
zPositionDesired1 -= 0.2;
cout << "New Z Setpoint: " << zPositionDesired1 << endl;
}
*/ //Commented out above inputs
if (keystroke_now == '1') {
yawDesired1 += 45.0;
cout << "New Yaw Setpoint: " << yawDesired1 << endl;
} else if (keystroke_now == '2') {
yawDesired1 -= 45.0;
cout << "New Yaw Setpoint: " << yawDesired1 << endl;
}
else if (keystroke_now == 'k') {
cflieCopter1->m_enumFlightMode = GROUNDED_MODE;
if(cflieCopter2){
cflieCopter2->m_enumFlightMode = GROUNDED_MODE;}
if(cflieCopter3){
cflieCopter3->m_enumFlightMode = GROUNDED_MODE;}
if(cflieCopter4){
cflieCopter4->m_enumFlightMode = GROUNDED_MODE;}
} else if (keystroke_now == 'e') {
cflieCopter1->m_enumFlightMode = LANDING_MODE;
if(cflieCopter2){
cflieCopter2->m_enumFlightMode = LANDING_MODE;}
if(cflieCopter3){
cflieCopter3->m_enumFlightMode = LANDING_MODE;}
if(cflieCopter4){
cflieCopter4->m_enumFlightMode = LANDING_MODE;}
handMode = 0;
// landingMode ^= 1;
// mirrorMode = 0;
cout << "Landing Mode Enabled" << endl;
} else if (keystroke_now == 'm') {
cflieCopter1->m_enumFlightMode = MIRROR_MODE;
if(cflieCopter2){
cflieCopter2->m_enumFlightMode = MIRROR_MODE;}
if(cflieCopter3){
cflieCopter3->m_enumFlightMode = MIRROR_MODE;}
if(cflieCopter4){
cflieCopter4->m_enumFlightMode = MIRROR_MODE;}
// mirrorMode ^= 1;
cout << "Mirror Mode Enabled" << endl;
} else if (keystroke_now == 'h') {
handMode = 1;
cout << "Hand Mode Enabled" << endl;
} else if (keystroke_now == 't') {
cflieCopter1->m_enumFlightMode = TAKEOFF_MODE;
// takeOff1 = 1;
takeOffTime1 = cflieCopter1->currentTime() - initTime1;
}
else if (keystroke_now == 'y') {
cflieCopter2->m_enumFlightMode = TAKEOFF_MODE;
// takeOff2 = 1;
takeOffTime2 = cflieCopter2->currentTime() - initTime2;
}
else if (keystroke_now == 'u') {
cflieCopter3->m_enumFlightMode = TAKEOFF_MODE;
// takeOff3 = 1;
takeOffTime3 = cflieCopter3->currentTime() - initTime3;
}
else if (keystroke_now == 'i') {
cflieCopter4->m_enumFlightMode = TAKEOFF_MODE;
// takeOff4 = 1;
takeOffTime4 = cflieCopter4->currentTime() - initTime4;
}
// else if (keystroke_now == '`') {
// tcp_server_ON ^= 1;
// } else if (keystroke_now == '1') {
// tcp_client_ON ^= 1;
// }
// else if (keystroke_now == 'o') {
// flap = 1;
// }
// else if (keystroke_now == 'l') {
// flap = 0;
// }
keystroke_prev = keystroke_now;
}
nonblock(0);
}//END readKeyboard()
</pre>
</code>
</blockquote>
::This is just a bunch of 'if' checks that activate if a certain key has been pressed.
::*So we can see that the first 8 options just simply add or subtract a constant value to a variable in the code whenever that key is pressed.
::*The options after that are what trigger different [[:Flight States]], telling the Crazyflie to do things like ''Take-Off'', or to ''Fly in Formation'', or to ''Land''. These are more complex functions and can change the behavior of the entire swarm! See the [[:Flight States]] page for more information on this.
----
<center> '''Main Directory''' </center>
<center> [[Crazyflie Swarm|Crazyflie Swarm Home]] | [[PC Client Software]] | [[USB Radio]] | [[Firmware]] | [[FAQ]] </center>
<center> '''Modifications Directory''' </center>
<center> [[Controller]] | [[Logging]] | [[Keyboard Commands]] | [[USB Radio#Changing Radio Channel|Changing Radio Channel]] | [[Flight Modes]] | [[Callbacks]] | [[Adding a Crazyflie]] | [[Firmware]] </center>
0ddfb5960eaf8c401cd3dc64e2d3d61c9e5ea0e3
139
138
2016-07-26T16:49:23Z
Jnoronha
3
Fixed flight state links to Flight Mode links
wikitext
text/x-wiki
Keyboard commands give the user the ability to modify variables during a flight test. The actions each key performs is completely customizable and can trigger anything from just adjusting a PID constant, to executing complex functions.
To get the basic idea of how the function works, here is a flow chart of the process and an example trigger:
[[Image:Keyboard_Input.png]]
==Reading the Keyboard Input==
We use the <code>select()</code> function for a non-blocking method to read the keyboard input from the <code>STDIN</code> file descriptor in linux. The function below is what we currently use to read the keyboard. (The function was provided by Dr. Phillip Jones):
:1. First we need to establish the base functions that we will use to read the key input (code found in ''vrpn.cpp''):
<blockquote>
<code>
<pre>
//////////////////////////////////////////////////
// kbhit //
// Descption: used select to do a non blocking //
// read of stdin. //
// //
//////////////////////////////////////////////////
int kbhit()
{
struct timeval tv;
fd_set fds;
tv.tv_sec = 0;
tv.tv_usec = 0;
FD_ZERO(&fds);
FD_SET(STDIN_FILENO, &fds); //STDIN_FILENO is 0
select(STDIN_FILENO+1, &fds, NULL, NULL, &tv);
return FD_ISSET(STDIN_FILENO, &fds);
}
</pre>
</code>
</blockquote>
::Then we can make it non-blocking code with the following:
<blockquote>
<code>
<pre>
//////////////////////////////////////////////////
// nonblock //
// Descption: Turn off connoical mode so the //
// user does not need to hit enter after //
// pressing a key //
// //
//////////////////////////////////////////////////
void nonblock(int state)
{
struct termios ttystate;
//get the terminal state
tcgetattr(STDIN_FILENO, &ttystate);
if (state==1)
{
//turn off canonical mode
ttystate.c_lflag &= ~ICANON;
//minimum of number input read.
ttystate.c_cc[VMIN] = 1;
}
else if (state==0)
{
//turn on canonical mode
ttystate.c_lflag |= ICANON;
}
//set the terminal attributes.
tcsetattr(STDIN_FILENO, TCSANOW, &ttystate);
}
</pre>
</code>
</blockquote>
:2. Reading the Keypress (code in ''vrpn.cpp''):
<blockquote>
<code>
<pre>
nonblock(1);
usleep(1);
i = kbhit(); //keyboard hit (state change)
if (i!=0) //If state has changed, read and record key value
{
keystroke_now = fgetc(stdin);
if (keystroke_now == 'q')
i=1;
else{
i=0;
}
} //END IF
readKeyboard(); //Uses key value input to trigger actions
</pre>
</code>
</blockquote>
::All this code is doing is checking the <code>STDIN</code> file descriptor for a state change, if it has then read that change and record the key value that was pressed.
:3. Using the Key value to trigger actions (code in ''vrpn.cpp''):
<blockquote>
<code>
<pre>
void readKeyboard()
{
//========Reads Keystrokes from Keyboard==========
nonblock(1);
if (keystroke_now != keystroke_prev) { //If the keyvalue has changed (Debouncing safety)
/*
if (keystroke_now == 'w') {
yPositionDesired1 -= 0.2;
cout << "New Y Setpoint: " << yPositionDesired1 << endl;
} else if (keystroke_now == 's') {
yPositionDesired1 += 0.2;
cout << "New Y Setpoint: " << yPositionDesired1 << endl;
} else if (keystroke_now == 'a') {
xPositionDesired1 -= 0.2;
cout << "New X Setpoint: " << xPositionDesired1 << endl;
} else if (keystroke_now == 'd') {
xPositionDesired1 += 0.2;
cout << "New X Setpoint: " << xPositionDesired1 << endl;
} else if (keystroke_now == 'r') {
zPositionDesired1 += 0.2;
cout << "New Z Setpoint: " << zPositionDesired1 << endl;
} else if (keystroke_now == 'f') {
zPositionDesired1 -= 0.2;
cout << "New Z Setpoint: " << zPositionDesired1 << endl;
}
*/ //Commented out above inputs
if (keystroke_now == '1') {
yawDesired1 += 45.0;
cout << "New Yaw Setpoint: " << yawDesired1 << endl;
} else if (keystroke_now == '2') {
yawDesired1 -= 45.0;
cout << "New Yaw Setpoint: " << yawDesired1 << endl;
}
else if (keystroke_now == 'k') {
cflieCopter1->m_enumFlightMode = GROUNDED_MODE;
if(cflieCopter2){
cflieCopter2->m_enumFlightMode = GROUNDED_MODE;}
if(cflieCopter3){
cflieCopter3->m_enumFlightMode = GROUNDED_MODE;}
if(cflieCopter4){
cflieCopter4->m_enumFlightMode = GROUNDED_MODE;}
} else if (keystroke_now == 'e') {
cflieCopter1->m_enumFlightMode = LANDING_MODE;
if(cflieCopter2){
cflieCopter2->m_enumFlightMode = LANDING_MODE;}
if(cflieCopter3){
cflieCopter3->m_enumFlightMode = LANDING_MODE;}
if(cflieCopter4){
cflieCopter4->m_enumFlightMode = LANDING_MODE;}
handMode = 0;
// landingMode ^= 1;
// mirrorMode = 0;
cout << "Landing Mode Enabled" << endl;
} else if (keystroke_now == 'm') {
cflieCopter1->m_enumFlightMode = MIRROR_MODE;
if(cflieCopter2){
cflieCopter2->m_enumFlightMode = MIRROR_MODE;}
if(cflieCopter3){
cflieCopter3->m_enumFlightMode = MIRROR_MODE;}
if(cflieCopter4){
cflieCopter4->m_enumFlightMode = MIRROR_MODE;}
// mirrorMode ^= 1;
cout << "Mirror Mode Enabled" << endl;
} else if (keystroke_now == 'h') {
handMode = 1;
cout << "Hand Mode Enabled" << endl;
} else if (keystroke_now == 't') {
cflieCopter1->m_enumFlightMode = TAKEOFF_MODE;
// takeOff1 = 1;
takeOffTime1 = cflieCopter1->currentTime() - initTime1;
}
else if (keystroke_now == 'y') {
cflieCopter2->m_enumFlightMode = TAKEOFF_MODE;
// takeOff2 = 1;
takeOffTime2 = cflieCopter2->currentTime() - initTime2;
}
else if (keystroke_now == 'u') {
cflieCopter3->m_enumFlightMode = TAKEOFF_MODE;
// takeOff3 = 1;
takeOffTime3 = cflieCopter3->currentTime() - initTime3;
}
else if (keystroke_now == 'i') {
cflieCopter4->m_enumFlightMode = TAKEOFF_MODE;
// takeOff4 = 1;
takeOffTime4 = cflieCopter4->currentTime() - initTime4;
}
// else if (keystroke_now == '`') {
// tcp_server_ON ^= 1;
// } else if (keystroke_now == '1') {
// tcp_client_ON ^= 1;
// }
// else if (keystroke_now == 'o') {
// flap = 1;
// }
// else if (keystroke_now == 'l') {
// flap = 0;
// }
keystroke_prev = keystroke_now;
}
nonblock(0);
}//END readKeyboard()
</pre>
</code>
</blockquote>
::This is just a bunch of 'if' checks that activate if a certain key has been pressed.
::*So we can see that the first 8 options just simply add or subtract a constant value to a variable in the code whenever that key is pressed.
::*The options after that are what trigger different [[:Flight Modes]], telling the Crazyflie to do things like ''Take-Off'', or to ''Fly in Formation'', or to ''Land''. These are more complex functions and can change the behavior of the entire swarm! See the [[:Flight Modes]] page for more information on this.
----
<center> '''Main Directory''' </center>
<center> [[Crazyflie Swarm|Crazyflie Swarm Home]] | [[PC Client Software]] | [[USB Radio]] | [[Firmware]] | [[FAQ]] </center>
<center> '''Modifications Directory''' </center>
<center> [[Controller]] | [[Logging]] | [[Keyboard Commands]] | [[USB Radio#Changing Radio Channel|Changing Radio Channel]] | [[Flight Modes]] | [[Callbacks]] | [[Adding a Crazyflie]] | [[Firmware]] </center>
94c96f056cf0d8431bf3d087e23faf9b10202091
140
139
2016-07-26T17:20:13Z
Jnoronha
3
added list of current keyboard commands
wikitext
text/x-wiki
Keyboard commands give the user the ability to modify variables during a flight test. The actions each key performs is completely customizable and can trigger anything from just adjusting a PID constant, to executing complex functions.
To get the basic idea of how the function works, here is a flow chart of the process and an example trigger:
[[Image:Keyboard_Input.png]]
==List of Current Keyboard Commands==
===Movement Commands===
::*'w' - Moves Crazyflie1 Forward by 0.2 meters (- y setpoint) '''(COMMENTED OUT)'''
::*'s' - Moves Crazyflie1 Backward by 0.2 meters (+ y setpoint) '''(COMMENTED OUT)'''
::*'a' - Moves Crazyflie1 Left by 0.2 meters (- x setpoint) '''(COMMENTED OUT)'''
::*'d' - Moves Crazyflie1 Right by 0.2 meters (+ x setpoint) '''(COMMENTED OUT)'''
::*'r' - Moves Crazyflie1 UP by 0.2 meters (+ z setpoint) '''(COMMENTED OUT)'''
::*'f' - Moves Crazyflie1 Down by 0.2 meters (- z setpoint) '''(COMMENTED OUT)'''
::*'1' - Rotates Yaw of Crazyflie1 +45 degrees
::*'2' - Rotates Yaw of Crazyflie1 -45 degrees
===Flight Mode Commands===
::*'k' - EMERGENCY STOP kill ALL Crazyflie engines '''(set all thrust to 0)'''
::*'h' - Hand Mode '''(for ALL Crazyflies)'''
::*'e' - Landing Mode '''(for ALL Crazyflies)'''
::*'t' - Crazyflie1 Take-Off
::*'y' - Crazyflie2 Take-Off
::*'u' - Crazyflie3 Take-Off
::*'i' - Crazyflie4 Take-Off
::*'h' - Hand Gesture Mode '''(for ALL Crazyflies)'''
::*'m' - Mirror Mode '''(for ALL Crazyflies)'''
===Utility Commands===
::*ctrl+c - Quits Program, performs all cleanup.
===Obsolete Key Commands===
::*'q' - Ends Main Loop '''(OBSOLETE - Replaced with ctrl + c)'''
::*'`' - Enables TCP Server on the Swarm Client (for '''sending''' information to Swarm Clients on different computers)
::*'l' - Enables TCP Client on the Swarm Client (for '''receiving''' information from Swarm Clients on different computers)
::*'o' - Enable Flap Mode (used for testing Crazyflie Powered Flapping Wing Project)
::*'1' - Disable Flap Mode
==Reading the Keyboard Input==
We use the <code>select()</code> function for a non-blocking method to read the keyboard input from the <code>STDIN</code> file descriptor in linux. The function below is what we currently use to read the keyboard. (The function was provided by Dr. Phillip Jones):
:1. First we need to establish the base functions that we will use to read the key input (code found in ''vrpn.cpp''):
<blockquote>
<code>
<pre>
//////////////////////////////////////////////////
// kbhit //
// Descption: used select to do a non blocking //
// read of stdin. //
// //
//////////////////////////////////////////////////
int kbhit()
{
struct timeval tv;
fd_set fds;
tv.tv_sec = 0;
tv.tv_usec = 0;
FD_ZERO(&fds);
FD_SET(STDIN_FILENO, &fds); //STDIN_FILENO is 0
select(STDIN_FILENO+1, &fds, NULL, NULL, &tv);
return FD_ISSET(STDIN_FILENO, &fds);
}
</pre>
</code>
</blockquote>
::Then we can make it non-blocking code with the following:
<blockquote>
<code>
<pre>
//////////////////////////////////////////////////
// nonblock //
// Descption: Turn off connoical mode so the //
// user does not need to hit enter after //
// pressing a key //
// //
//////////////////////////////////////////////////
void nonblock(int state)
{
struct termios ttystate;
//get the terminal state
tcgetattr(STDIN_FILENO, &ttystate);
if (state==1)
{
//turn off canonical mode
ttystate.c_lflag &= ~ICANON;
//minimum of number input read.
ttystate.c_cc[VMIN] = 1;
}
else if (state==0)
{
//turn on canonical mode
ttystate.c_lflag |= ICANON;
}
//set the terminal attributes.
tcsetattr(STDIN_FILENO, TCSANOW, &ttystate);
}
</pre>
</code>
</blockquote>
:2. Reading the Keypress (code in ''vrpn.cpp''):
<blockquote>
<code>
<pre>
nonblock(1);
usleep(1);
i = kbhit(); //keyboard hit (state change)
if (i!=0) //If state has changed, read and record key value
{
keystroke_now = fgetc(stdin);
if (keystroke_now == 'q')
i=1;
else{
i=0;
}
} //END IF
readKeyboard(); //Uses key value input to trigger actions
</pre>
</code>
</blockquote>
::All this code is doing is checking the <code>STDIN</code> file descriptor for a state change, if it has then read that change and record the key value that was pressed.
:3. Using the Key value to trigger actions (code in ''vrpn.cpp''):
<blockquote>
<code>
<pre>
void readKeyboard()
{
//========Reads Keystrokes from Keyboard==========
nonblock(1);
if (keystroke_now != keystroke_prev) { //If the keyvalue has changed (Debouncing safety)
/*
if (keystroke_now == 'w') {
yPositionDesired1 -= 0.2;
cout << "New Y Setpoint: " << yPositionDesired1 << endl;
} else if (keystroke_now == 's') {
yPositionDesired1 += 0.2;
cout << "New Y Setpoint: " << yPositionDesired1 << endl;
} else if (keystroke_now == 'a') {
xPositionDesired1 -= 0.2;
cout << "New X Setpoint: " << xPositionDesired1 << endl;
} else if (keystroke_now == 'd') {
xPositionDesired1 += 0.2;
cout << "New X Setpoint: " << xPositionDesired1 << endl;
} else if (keystroke_now == 'r') {
zPositionDesired1 += 0.2;
cout << "New Z Setpoint: " << zPositionDesired1 << endl;
} else if (keystroke_now == 'f') {
zPositionDesired1 -= 0.2;
cout << "New Z Setpoint: " << zPositionDesired1 << endl;
}
*/ //Commented out above inputs
if (keystroke_now == '1') {
yawDesired1 += 45.0;
cout << "New Yaw Setpoint: " << yawDesired1 << endl;
} else if (keystroke_now == '2') {
yawDesired1 -= 45.0;
cout << "New Yaw Setpoint: " << yawDesired1 << endl;
}
else if (keystroke_now == 'k') {
cflieCopter1->m_enumFlightMode = GROUNDED_MODE;
if(cflieCopter2){
cflieCopter2->m_enumFlightMode = GROUNDED_MODE;}
if(cflieCopter3){
cflieCopter3->m_enumFlightMode = GROUNDED_MODE;}
if(cflieCopter4){
cflieCopter4->m_enumFlightMode = GROUNDED_MODE;}
} else if (keystroke_now == 'e') {
cflieCopter1->m_enumFlightMode = LANDING_MODE;
if(cflieCopter2){
cflieCopter2->m_enumFlightMode = LANDING_MODE;}
if(cflieCopter3){
cflieCopter3->m_enumFlightMode = LANDING_MODE;}
if(cflieCopter4){
cflieCopter4->m_enumFlightMode = LANDING_MODE;}
handMode = 0;
// landingMode ^= 1;
// mirrorMode = 0;
cout << "Landing Mode Enabled" << endl;
} else if (keystroke_now == 'm') {
cflieCopter1->m_enumFlightMode = MIRROR_MODE;
if(cflieCopter2){
cflieCopter2->m_enumFlightMode = MIRROR_MODE;}
if(cflieCopter3){
cflieCopter3->m_enumFlightMode = MIRROR_MODE;}
if(cflieCopter4){
cflieCopter4->m_enumFlightMode = MIRROR_MODE;}
// mirrorMode ^= 1;
cout << "Mirror Mode Enabled" << endl;
} else if (keystroke_now == 'h') {
handMode = 1;
cout << "Hand Mode Enabled" << endl;
} else if (keystroke_now == 't') {
cflieCopter1->m_enumFlightMode = TAKEOFF_MODE;
// takeOff1 = 1;
takeOffTime1 = cflieCopter1->currentTime() - initTime1;
}
else if (keystroke_now == 'y') {
cflieCopter2->m_enumFlightMode = TAKEOFF_MODE;
// takeOff2 = 1;
takeOffTime2 = cflieCopter2->currentTime() - initTime2;
}
else if (keystroke_now == 'u') {
cflieCopter3->m_enumFlightMode = TAKEOFF_MODE;
// takeOff3 = 1;
takeOffTime3 = cflieCopter3->currentTime() - initTime3;
}
else if (keystroke_now == 'i') {
cflieCopter4->m_enumFlightMode = TAKEOFF_MODE;
// takeOff4 = 1;
takeOffTime4 = cflieCopter4->currentTime() - initTime4;
}
// else if (keystroke_now == '`') {
// tcp_server_ON ^= 1;
// } else if (keystroke_now == '1') {
// tcp_client_ON ^= 1;
// }
// else if (keystroke_now == 'o') {
// flap = 1;
// }
// else if (keystroke_now == 'l') {
// flap = 0;
// }
keystroke_prev = keystroke_now;
}
nonblock(0);
}//END readKeyboard()
</pre>
</code>
</blockquote>
::This is just a bunch of 'if' checks that activate if a certain key has been pressed.
::*So we can see that the first 8 options just simply add or subtract a constant value to a variable in the code whenever that key is pressed.
::*The options after that are what trigger different [[:Flight Modes]], telling the Crazyflie to do things like ''Take-Off'', or to ''Fly in Formation'', or to ''Land''. These are more complex functions and can change the behavior of the entire swarm! See the [[:Flight Modes]] page for more information on this.
----
<center> '''Main Directory''' </center>
<center> [[Crazyflie Swarm|Crazyflie Swarm Home]] | [[PC Client Software]] | [[USB Radio]] | [[Firmware]] | [[FAQ]] </center>
<center> '''Modifications Directory''' </center>
<center> [[Controller]] | [[Logging]] | [[Keyboard Commands]] | [[USB Radio#Changing Radio Channel|Changing Radio Channel]] | [[Flight Modes]] | [[Callbacks]] | [[Adding a Crazyflie]] | [[Firmware]] </center>
eaa81d95ade4003bd6b25c6a0a2e902bbaa474f7
141
140
2016-07-26T17:21:20Z
Jnoronha
3
Added command list timestamp
wikitext
text/x-wiki
Keyboard commands give the user the ability to modify variables during a flight test. The actions each key performs is completely customizable and can trigger anything from just adjusting a PID constant, to executing complex functions.
To get the basic idea of how the function works, here is a flow chart of the process and an example trigger:
[[Image:Keyboard_Input.png]]
==List of Current Keyboard Commands==
(Command List as of 7/26/16)
===Movement Commands===
::*'w' - Moves Crazyflie1 Forward by 0.2 meters (- y setpoint) '''(COMMENTED OUT)'''
::*'s' - Moves Crazyflie1 Backward by 0.2 meters (+ y setpoint) '''(COMMENTED OUT)'''
::*'a' - Moves Crazyflie1 Left by 0.2 meters (- x setpoint) '''(COMMENTED OUT)'''
::*'d' - Moves Crazyflie1 Right by 0.2 meters (+ x setpoint) '''(COMMENTED OUT)'''
::*'r' - Moves Crazyflie1 UP by 0.2 meters (+ z setpoint) '''(COMMENTED OUT)'''
::*'f' - Moves Crazyflie1 Down by 0.2 meters (- z setpoint) '''(COMMENTED OUT)'''
::*'1' - Rotates Yaw of Crazyflie1 +45 degrees
::*'2' - Rotates Yaw of Crazyflie1 -45 degrees
===Flight Mode Commands===
::*'k' - EMERGENCY STOP kill ALL Crazyflie engines '''(set all thrust to 0)'''
::*'h' - Hand Mode '''(for ALL Crazyflies)'''
::*'e' - Landing Mode '''(for ALL Crazyflies)'''
::*'t' - Crazyflie1 Take-Off
::*'y' - Crazyflie2 Take-Off
::*'u' - Crazyflie3 Take-Off
::*'i' - Crazyflie4 Take-Off
::*'h' - Hand Gesture Mode '''(for ALL Crazyflies)'''
::*'m' - Mirror Mode '''(for ALL Crazyflies)'''
===Utility Commands===
::*ctrl+c - Quits Program, performs all cleanup.
===Obsolete Key Commands===
::*'q' - Ends Main Loop '''(OBSOLETE - Replaced with ctrl + c)'''
::*'`' - Enables TCP Server on the Swarm Client (for '''sending''' information to Swarm Clients on different computers)
::*'l' - Enables TCP Client on the Swarm Client (for '''receiving''' information from Swarm Clients on different computers)
::*'o' - Enable Flap Mode (used for testing Crazyflie Powered Flapping Wing Project)
::*'1' - Disable Flap Mode
==Reading the Keyboard Input==
We use the <code>select()</code> function for a non-blocking method to read the keyboard input from the <code>STDIN</code> file descriptor in linux. The function below is what we currently use to read the keyboard. (The function was provided by Dr. Phillip Jones):
:1. First we need to establish the base functions that we will use to read the key input (code found in ''vrpn.cpp''):
<blockquote>
<code>
<pre>
//////////////////////////////////////////////////
// kbhit //
// Descption: used select to do a non blocking //
// read of stdin. //
// //
//////////////////////////////////////////////////
int kbhit()
{
struct timeval tv;
fd_set fds;
tv.tv_sec = 0;
tv.tv_usec = 0;
FD_ZERO(&fds);
FD_SET(STDIN_FILENO, &fds); //STDIN_FILENO is 0
select(STDIN_FILENO+1, &fds, NULL, NULL, &tv);
return FD_ISSET(STDIN_FILENO, &fds);
}
</pre>
</code>
</blockquote>
::Then we can make it non-blocking code with the following:
<blockquote>
<code>
<pre>
//////////////////////////////////////////////////
// nonblock //
// Descption: Turn off connoical mode so the //
// user does not need to hit enter after //
// pressing a key //
// //
//////////////////////////////////////////////////
void nonblock(int state)
{
struct termios ttystate;
//get the terminal state
tcgetattr(STDIN_FILENO, &ttystate);
if (state==1)
{
//turn off canonical mode
ttystate.c_lflag &= ~ICANON;
//minimum of number input read.
ttystate.c_cc[VMIN] = 1;
}
else if (state==0)
{
//turn on canonical mode
ttystate.c_lflag |= ICANON;
}
//set the terminal attributes.
tcsetattr(STDIN_FILENO, TCSANOW, &ttystate);
}
</pre>
</code>
</blockquote>
:2. Reading the Keypress (code in ''vrpn.cpp''):
<blockquote>
<code>
<pre>
nonblock(1);
usleep(1);
i = kbhit(); //keyboard hit (state change)
if (i!=0) //If state has changed, read and record key value
{
keystroke_now = fgetc(stdin);
if (keystroke_now == 'q')
i=1;
else{
i=0;
}
} //END IF
readKeyboard(); //Uses key value input to trigger actions
</pre>
</code>
</blockquote>
::All this code is doing is checking the <code>STDIN</code> file descriptor for a state change, if it has then read that change and record the key value that was pressed.
:3. Using the Key value to trigger actions (code in ''vrpn.cpp''):
<blockquote>
<code>
<pre>
void readKeyboard()
{
//========Reads Keystrokes from Keyboard==========
nonblock(1);
if (keystroke_now != keystroke_prev) { //If the keyvalue has changed (Debouncing safety)
/*
if (keystroke_now == 'w') {
yPositionDesired1 -= 0.2;
cout << "New Y Setpoint: " << yPositionDesired1 << endl;
} else if (keystroke_now == 's') {
yPositionDesired1 += 0.2;
cout << "New Y Setpoint: " << yPositionDesired1 << endl;
} else if (keystroke_now == 'a') {
xPositionDesired1 -= 0.2;
cout << "New X Setpoint: " << xPositionDesired1 << endl;
} else if (keystroke_now == 'd') {
xPositionDesired1 += 0.2;
cout << "New X Setpoint: " << xPositionDesired1 << endl;
} else if (keystroke_now == 'r') {
zPositionDesired1 += 0.2;
cout << "New Z Setpoint: " << zPositionDesired1 << endl;
} else if (keystroke_now == 'f') {
zPositionDesired1 -= 0.2;
cout << "New Z Setpoint: " << zPositionDesired1 << endl;
}
*/ //Commented out above inputs
if (keystroke_now == '1') {
yawDesired1 += 45.0;
cout << "New Yaw Setpoint: " << yawDesired1 << endl;
} else if (keystroke_now == '2') {
yawDesired1 -= 45.0;
cout << "New Yaw Setpoint: " << yawDesired1 << endl;
}
else if (keystroke_now == 'k') {
cflieCopter1->m_enumFlightMode = GROUNDED_MODE;
if(cflieCopter2){
cflieCopter2->m_enumFlightMode = GROUNDED_MODE;}
if(cflieCopter3){
cflieCopter3->m_enumFlightMode = GROUNDED_MODE;}
if(cflieCopter4){
cflieCopter4->m_enumFlightMode = GROUNDED_MODE;}
} else if (keystroke_now == 'e') {
cflieCopter1->m_enumFlightMode = LANDING_MODE;
if(cflieCopter2){
cflieCopter2->m_enumFlightMode = LANDING_MODE;}
if(cflieCopter3){
cflieCopter3->m_enumFlightMode = LANDING_MODE;}
if(cflieCopter4){
cflieCopter4->m_enumFlightMode = LANDING_MODE;}
handMode = 0;
// landingMode ^= 1;
// mirrorMode = 0;
cout << "Landing Mode Enabled" << endl;
} else if (keystroke_now == 'm') {
cflieCopter1->m_enumFlightMode = MIRROR_MODE;
if(cflieCopter2){
cflieCopter2->m_enumFlightMode = MIRROR_MODE;}
if(cflieCopter3){
cflieCopter3->m_enumFlightMode = MIRROR_MODE;}
if(cflieCopter4){
cflieCopter4->m_enumFlightMode = MIRROR_MODE;}
// mirrorMode ^= 1;
cout << "Mirror Mode Enabled" << endl;
} else if (keystroke_now == 'h') {
handMode = 1;
cout << "Hand Mode Enabled" << endl;
} else if (keystroke_now == 't') {
cflieCopter1->m_enumFlightMode = TAKEOFF_MODE;
// takeOff1 = 1;
takeOffTime1 = cflieCopter1->currentTime() - initTime1;
}
else if (keystroke_now == 'y') {
cflieCopter2->m_enumFlightMode = TAKEOFF_MODE;
// takeOff2 = 1;
takeOffTime2 = cflieCopter2->currentTime() - initTime2;
}
else if (keystroke_now == 'u') {
cflieCopter3->m_enumFlightMode = TAKEOFF_MODE;
// takeOff3 = 1;
takeOffTime3 = cflieCopter3->currentTime() - initTime3;
}
else if (keystroke_now == 'i') {
cflieCopter4->m_enumFlightMode = TAKEOFF_MODE;
// takeOff4 = 1;
takeOffTime4 = cflieCopter4->currentTime() - initTime4;
}
// else if (keystroke_now == '`') {
// tcp_server_ON ^= 1;
// } else if (keystroke_now == '1') {
// tcp_client_ON ^= 1;
// }
// else if (keystroke_now == 'o') {
// flap = 1;
// }
// else if (keystroke_now == 'l') {
// flap = 0;
// }
keystroke_prev = keystroke_now;
}
nonblock(0);
}//END readKeyboard()
</pre>
</code>
</blockquote>
::This is just a bunch of 'if' checks that activate if a certain key has been pressed.
::*So we can see that the first 8 options just simply add or subtract a constant value to a variable in the code whenever that key is pressed.
::*The options after that are what trigger different [[:Flight Modes]], telling the Crazyflie to do things like ''Take-Off'', or to ''Fly in Formation'', or to ''Land''. These are more complex functions and can change the behavior of the entire swarm! See the [[:Flight Modes]] page for more information on this.
----
<center> '''Main Directory''' </center>
<center> [[Crazyflie Swarm|Crazyflie Swarm Home]] | [[PC Client Software]] | [[USB Radio]] | [[Firmware]] | [[FAQ]] </center>
<center> '''Modifications Directory''' </center>
<center> [[Controller]] | [[Logging]] | [[Keyboard Commands]] | [[USB Radio#Changing Radio Channel|Changing Radio Channel]] | [[Flight Modes]] | [[Callbacks]] | [[Adding a Crazyflie]] | [[Firmware]] </center>
a1db84aa1d4464fc91461da06e5f633d451fdfc8
142
141
2016-07-26T17:23:24Z
Jnoronha
3
spaced the directory footer better
wikitext
text/x-wiki
Keyboard commands give the user the ability to modify variables during a flight test. The actions each key performs is completely customizable and can trigger anything from just adjusting a PID constant, to executing complex functions.
To get the basic idea of how the function works, here is a flow chart of the process and an example trigger:
[[Image:Keyboard_Input.png]]
==List of Current Keyboard Commands==
(Command List as of 7/26/16)
===Movement Commands===
::*'w' - Moves Crazyflie1 Forward by 0.2 meters (- y setpoint) '''(COMMENTED OUT)'''
::*'s' - Moves Crazyflie1 Backward by 0.2 meters (+ y setpoint) '''(COMMENTED OUT)'''
::*'a' - Moves Crazyflie1 Left by 0.2 meters (- x setpoint) '''(COMMENTED OUT)'''
::*'d' - Moves Crazyflie1 Right by 0.2 meters (+ x setpoint) '''(COMMENTED OUT)'''
::*'r' - Moves Crazyflie1 UP by 0.2 meters (+ z setpoint) '''(COMMENTED OUT)'''
::*'f' - Moves Crazyflie1 Down by 0.2 meters (- z setpoint) '''(COMMENTED OUT)'''
::*'1' - Rotates Yaw of Crazyflie1 +45 degrees
::*'2' - Rotates Yaw of Crazyflie1 -45 degrees
===Flight Mode Commands===
::*'k' - EMERGENCY STOP kill ALL Crazyflie engines '''(set all thrust to 0)'''
::*'h' - Hand Mode '''(for ALL Crazyflies)'''
::*'e' - Landing Mode '''(for ALL Crazyflies)'''
::*'t' - Crazyflie1 Take-Off
::*'y' - Crazyflie2 Take-Off
::*'u' - Crazyflie3 Take-Off
::*'i' - Crazyflie4 Take-Off
::*'h' - Hand Gesture Mode '''(for ALL Crazyflies)'''
::*'m' - Mirror Mode '''(for ALL Crazyflies)'''
===Utility Commands===
::*ctrl+c - Quits Program, performs all cleanup.
===Obsolete Key Commands===
::*'q' - Ends Main Loop '''(OBSOLETE - Replaced with ctrl + c)'''
::*'`' - Enables TCP Server on the Swarm Client (for '''sending''' information to Swarm Clients on different computers)
::*'l' - Enables TCP Client on the Swarm Client (for '''receiving''' information from Swarm Clients on different computers)
::*'o' - Enable Flap Mode (used for testing Crazyflie Powered Flapping Wing Project)
::*'1' - Disable Flap Mode
==Reading the Keyboard Input==
We use the <code>select()</code> function for a non-blocking method to read the keyboard input from the <code>STDIN</code> file descriptor in linux. The function below is what we currently use to read the keyboard. (The function was provided by Dr. Phillip Jones):
:1. First we need to establish the base functions that we will use to read the key input (code found in ''vrpn.cpp''):
<blockquote>
<code>
<pre>
//////////////////////////////////////////////////
// kbhit //
// Descption: used select to do a non blocking //
// read of stdin. //
// //
//////////////////////////////////////////////////
int kbhit()
{
struct timeval tv;
fd_set fds;
tv.tv_sec = 0;
tv.tv_usec = 0;
FD_ZERO(&fds);
FD_SET(STDIN_FILENO, &fds); //STDIN_FILENO is 0
select(STDIN_FILENO+1, &fds, NULL, NULL, &tv);
return FD_ISSET(STDIN_FILENO, &fds);
}
</pre>
</code>
</blockquote>
::Then we can make it non-blocking code with the following:
<blockquote>
<code>
<pre>
//////////////////////////////////////////////////
// nonblock //
// Descption: Turn off connoical mode so the //
// user does not need to hit enter after //
// pressing a key //
// //
//////////////////////////////////////////////////
void nonblock(int state)
{
struct termios ttystate;
//get the terminal state
tcgetattr(STDIN_FILENO, &ttystate);
if (state==1)
{
//turn off canonical mode
ttystate.c_lflag &= ~ICANON;
//minimum of number input read.
ttystate.c_cc[VMIN] = 1;
}
else if (state==0)
{
//turn on canonical mode
ttystate.c_lflag |= ICANON;
}
//set the terminal attributes.
tcsetattr(STDIN_FILENO, TCSANOW, &ttystate);
}
</pre>
</code>
</blockquote>
:2. Reading the Keypress (code in ''vrpn.cpp''):
<blockquote>
<code>
<pre>
nonblock(1);
usleep(1);
i = kbhit(); //keyboard hit (state change)
if (i!=0) //If state has changed, read and record key value
{
keystroke_now = fgetc(stdin);
if (keystroke_now == 'q')
i=1;
else{
i=0;
}
} //END IF
readKeyboard(); //Uses key value input to trigger actions
</pre>
</code>
</blockquote>
::All this code is doing is checking the <code>STDIN</code> file descriptor for a state change, if it has then read that change and record the key value that was pressed.
:3. Using the Key value to trigger actions (code in ''vrpn.cpp''):
<blockquote>
<code>
<pre>
void readKeyboard()
{
//========Reads Keystrokes from Keyboard==========
nonblock(1);
if (keystroke_now != keystroke_prev) { //If the keyvalue has changed (Debouncing safety)
/*
if (keystroke_now == 'w') {
yPositionDesired1 -= 0.2;
cout << "New Y Setpoint: " << yPositionDesired1 << endl;
} else if (keystroke_now == 's') {
yPositionDesired1 += 0.2;
cout << "New Y Setpoint: " << yPositionDesired1 << endl;
} else if (keystroke_now == 'a') {
xPositionDesired1 -= 0.2;
cout << "New X Setpoint: " << xPositionDesired1 << endl;
} else if (keystroke_now == 'd') {
xPositionDesired1 += 0.2;
cout << "New X Setpoint: " << xPositionDesired1 << endl;
} else if (keystroke_now == 'r') {
zPositionDesired1 += 0.2;
cout << "New Z Setpoint: " << zPositionDesired1 << endl;
} else if (keystroke_now == 'f') {
zPositionDesired1 -= 0.2;
cout << "New Z Setpoint: " << zPositionDesired1 << endl;
}
*/ //Commented out above inputs
if (keystroke_now == '1') {
yawDesired1 += 45.0;
cout << "New Yaw Setpoint: " << yawDesired1 << endl;
} else if (keystroke_now == '2') {
yawDesired1 -= 45.0;
cout << "New Yaw Setpoint: " << yawDesired1 << endl;
}
else if (keystroke_now == 'k') {
cflieCopter1->m_enumFlightMode = GROUNDED_MODE;
if(cflieCopter2){
cflieCopter2->m_enumFlightMode = GROUNDED_MODE;}
if(cflieCopter3){
cflieCopter3->m_enumFlightMode = GROUNDED_MODE;}
if(cflieCopter4){
cflieCopter4->m_enumFlightMode = GROUNDED_MODE;}
} else if (keystroke_now == 'e') {
cflieCopter1->m_enumFlightMode = LANDING_MODE;
if(cflieCopter2){
cflieCopter2->m_enumFlightMode = LANDING_MODE;}
if(cflieCopter3){
cflieCopter3->m_enumFlightMode = LANDING_MODE;}
if(cflieCopter4){
cflieCopter4->m_enumFlightMode = LANDING_MODE;}
handMode = 0;
// landingMode ^= 1;
// mirrorMode = 0;
cout << "Landing Mode Enabled" << endl;
} else if (keystroke_now == 'm') {
cflieCopter1->m_enumFlightMode = MIRROR_MODE;
if(cflieCopter2){
cflieCopter2->m_enumFlightMode = MIRROR_MODE;}
if(cflieCopter3){
cflieCopter3->m_enumFlightMode = MIRROR_MODE;}
if(cflieCopter4){
cflieCopter4->m_enumFlightMode = MIRROR_MODE;}
// mirrorMode ^= 1;
cout << "Mirror Mode Enabled" << endl;
} else if (keystroke_now == 'h') {
handMode = 1;
cout << "Hand Mode Enabled" << endl;
} else if (keystroke_now == 't') {
cflieCopter1->m_enumFlightMode = TAKEOFF_MODE;
// takeOff1 = 1;
takeOffTime1 = cflieCopter1->currentTime() - initTime1;
}
else if (keystroke_now == 'y') {
cflieCopter2->m_enumFlightMode = TAKEOFF_MODE;
// takeOff2 = 1;
takeOffTime2 = cflieCopter2->currentTime() - initTime2;
}
else if (keystroke_now == 'u') {
cflieCopter3->m_enumFlightMode = TAKEOFF_MODE;
// takeOff3 = 1;
takeOffTime3 = cflieCopter3->currentTime() - initTime3;
}
else if (keystroke_now == 'i') {
cflieCopter4->m_enumFlightMode = TAKEOFF_MODE;
// takeOff4 = 1;
takeOffTime4 = cflieCopter4->currentTime() - initTime4;
}
// else if (keystroke_now == '`') {
// tcp_server_ON ^= 1;
// } else if (keystroke_now == '1') {
// tcp_client_ON ^= 1;
// }
// else if (keystroke_now == 'o') {
// flap = 1;
// }
// else if (keystroke_now == 'l') {
// flap = 0;
// }
keystroke_prev = keystroke_now;
}
nonblock(0);
}//END readKeyboard()
</pre>
</code>
</blockquote>
::This is just a bunch of 'if' checks that activate if a certain key has been pressed.
::*So we can see that the first 8 options just simply add or subtract a constant value to a variable in the code whenever that key is pressed.
::*The options after that are what trigger different [[:Flight Modes]], telling the Crazyflie to do things like ''Take-Off'', or to ''Fly in Formation'', or to ''Land''. These are more complex functions and can change the behavior of the entire swarm! See the [[:Flight Modes]] page for more information on this.
----
<center> '''Main Directory''' </center>
<center> [[Crazyflie Swarm|Crazyflie Swarm Home]] | [[PC Client Software]] | [[USB Radio]] | [[Firmware]] | [[FAQ]] </center>
<center> '''Modifications Directory''' </center>
<center> [[Controller]] | [[Logging]] | [[Keyboard Commands]] | [[USB Radio#Changing Radio Channel|Changing Radio Channel]] | [[Flight Modes]] | [[Callbacks]] | [[Adding a Crazyflie]] | [[Firmware]] </center>
457c7874d7c4bf2e27585caaf674df862324c21a
Flight Modes
0
42
143
2016-07-26T17:55:07Z
Jnoronha
3
Created list of flight modes
wikitext
text/x-wiki
Flight modes are a framework we created to allow changes to be made to the Flight behavior of the Crazyflies during a test. They have been implemented as an enum structure so that only one flight mode can be active at a time. Each Crazyflie has its own independent flight modes, so we can customize the flight patterns of each Crazyflie in the swarm separately, or as a group.
The enum is shown below (code in ''CCrazyflie.h''):
<blockquote>
<code>
<pre>
enum FlightMode{
LANDING_MODE = 0,
TAKEOFF_MODE = 1,
HOVER_MODE = 2,
MIRROR_MODE = 3,
HAND_MODE = 4,
GROUNDED_MODE = 5,
STEP_MODE = 6,
KILL_MODE = 7
};
</pre>
</code>
</blockquote>
==Current Flight Modes==
(List as of 7/26/16)
===Simple Flight Modes===
:*Landing Mode (0):
:**Changes z-setpoint to 0 and when Crazyflie is close enough to the ground automatically switch to ''Grounded Mode''
:*TakeOff Mode (1):
:**Enable PID controller for autonomous flight, hold position at default coordinates
:*Grounded Mode (5):
:**Crazyflies Setpoints Forced to 0, NO CONTROLLER CALCULATION DONE (used for sitting on the ground waiting for command)
:**'''Note:''' Also resets Controller Error to prevent integrator wind-up
===Formation Flight Modes===
:*Mirror Mode (3):
:**Swarm Forms a Triangle around Crazyflie 1
:**Crazyflie 1 Moves in a Step Pattern (diagonally back and forth)
:**Crazyflies 2, 3, and 4 follow Crazyflie 1 while maintaining the Triangle Formation
:*Hand Mode (4):
:**Crazyflies wait for Hand Gesture Commands
===Unused Flight Modes===
:*Hover Mode (2):
:**'''Not used yet''' (Could be used to reset the Crazyflie setpoints back to default)
:*Step Mode (6):
:**Similar to Crazyflie1's behavior when in Mirror Mode, but for all Crazyflies (used to verify Model Parameters).
:*Kill Mode (7):
:**Discontinued version of Grounded Mode (forces all setpoints to 0 but would continue calculating Controller)
==Landing Mode==
Landing Mode is more complex than some of the other modes in that when a certain condition is reached, it will automatically switch to a different Flight Mode.
[[Image:Landing_Mode.png]]
----
<center> '''Main Directory''' </center>
<center> [[Crazyflie Swarm|Crazyflie Swarm Home]] | [[PC Client Software]] | [[USB Radio]] | [[Firmware]] | [[FAQ]] </center>
<center> '''Modifications Directory''' </center>
<center> [[Controller]] | [[Logging]] | [[Keyboard Commands]] | [[USB Radio#Changing Radio Channel|Changing Radio Channel]] | [[Flight Modes]] | [[Callbacks]] | [[Adding a Crazyflie]] | [[Firmware]] </center>
f8887e808f5f60e9846f90c339ee5d30615cbbfb
144
143
2016-07-26T18:04:49Z
Jnoronha
3
Added detailed landing mode
wikitext
text/x-wiki
Flight modes are a framework we created to allow changes to be made to the Flight behavior of the Crazyflies during a test. They have been implemented as an enum structure so that only one flight mode can be active at a time. Each Crazyflie has its own independent flight modes, so we can customize the flight patterns of each Crazyflie in the swarm separately, or as a group.
The enum is shown below (code in ''CCrazyflie.h''):
<blockquote>
<code>
<pre>
enum FlightMode{
LANDING_MODE = 0,
TAKEOFF_MODE = 1,
HOVER_MODE = 2,
MIRROR_MODE = 3,
HAND_MODE = 4,
GROUNDED_MODE = 5,
STEP_MODE = 6,
KILL_MODE = 7
};
</pre>
</code>
</blockquote>
==Current Flight Modes==
(List as of 7/26/16)
===Simple Flight Modes===
:*'''Landing Mode (0):'''
:**Changes z-setpoint to 0 and when Crazyflie is close enough to the ground automatically switch to ''Grounded Mode''
:*'''TakeOff Mode (1):'''
:**Enable PID controller for autonomous flight, hold position at default coordinates
:*'''Grounded Mode (5):'''
:**Crazyflies Setpoints Forced to 0, NO CONTROLLER CALCULATION DONE (used for sitting on the ground waiting for command)
:**'''Note:''' Also resets Controller Error to prevent integrator wind-up
===Formation Flight Modes===
:*'''Mirror Mode (3):'''
:**Swarm Forms a Triangle around Crazyflie 1
:**Crazyflie 1 Moves in a Step Pattern (diagonally back and forth)
:**Crazyflies 2, 3, and 4 follow Crazyflie 1 while maintaining the Triangle Formation
:*'''Hand Mode (4):'''
:**Crazyflies wait for Hand Gesture Commands
===Unused Flight Modes===
:*'''Hover Mode (2):'''
:**'''Not used yet''' (Could be used to reset the Crazyflie setpoints back to default)
:*'''Step Mode (6):'''
:**Similar to Crazyflie1's behavior when in Mirror Mode, but for all Crazyflies (used to verify Model Parameters).
:*'''Kill Mode (7):'''
:**Discontinued version of Grounded Mode (forces all setpoints to 0 but would continue calculating Controller)
==Landing Mode==
Landing Mode is more complex than some of the other modes in that when a certain condition is reached, it will automatically switch to a different Flight Mode. A flow chart of the process is shown here:
[[Image:LandingMode.png|300px]]
And the code used to implement this is shown below (code in ''vrpn.cpp''):
<blockquote>
<code>
<pre>
void nearGround() //During Landing Mode checks how close to ground quad is for shutdown
{
if((cflieCopter1->m_enumFlightMode == LANDING_MODE) && (zPosition1 < 0.05))
{
cflieCopter1->m_enumFlightMode = GROUNDED_MODE;
}
if(cflieCopter2){ //Only sends command if Crazyflie 2 exists for this test (CLIENT WILL CRASH IF COMMANDING NON-EXISTENT CRAZYFLIE)
if((cflieCopter2->m_enumFlightMode == LANDING_MODE) && (zPosition2 < 0.05))
{
cflieCopter2->m_enumFlightMode = GROUNDED_MODE;
}
}
if(cflieCopter3){ //Only sends command if Crazyflie 3 exists for this test
if((cflieCopter3->m_enumFlightMode == LANDING_MODE) && (zPosition3 < 0.05))
{
cflieCopter3->m_enumFlightMode = GROUNDED_MODE;
}
}
if(cflieCopter4){ //Only sends command if Crazyflie 4 exists for this test
if((cflieCopter4->m_enumFlightMode == LANDING_MODE) && (zPosition4 < 0.05))
{
cflieCopter4->m_enumFlightMode = GROUNDED_MODE;
}
}
}
</pre>
</code>
</blockquote>
::This function is scanned at each iteration of the mainloop.
----
<center> '''Main Directory''' </center>
<center> [[Crazyflie Swarm|Crazyflie Swarm Home]] | [[PC Client Software]] | [[USB Radio]] | [[Firmware]] | [[FAQ]] </center>
<center> '''Modifications Directory''' </center>
<center> [[Controller]] | [[Logging]] | [[Keyboard Commands]] | [[USB Radio#Changing Radio Channel|Changing Radio Channel]] | [[Flight Modes]] | [[Callbacks]] | [[Adding a Crazyflie]] | [[Firmware]] </center>
b15b1bc8c2dfa5e02d9310f600f9bf894ee8cc50
File:TrackingToolsCrazyflieConstellationZeroing.png
6
43
145
2016-07-27T17:46:40Z
Jnoronha
3
Camera System Software with Crazyflie and Hand Constellations loaded
wikitext
text/x-wiki
Camera System Software with Crazyflie and Hand Constellations loaded
b20b4b16a3427dc104687a0ec094c2df21a8b1d5
Callbacks
0
44
146
2016-07-27T18:00:09Z
Jnoronha
3
added registering the Callbacks
wikitext
text/x-wiki
A callback is a segment of code that will run only when a certain condition is satisfied. For the Swarm Platform, the callbacks we use are triggered by the VRPN communications protocol used by the Camera System. Whenever the Client receives a new packet of data from the Camera System the callback will be triggered.
==Registering a Callback==
Before we can do anything we need to set up a callback that executes when new data is present.
:1. Use the VRPN Library to create a ''Connection'' and ''Tracker_Remote'' object pointers (code in ''vrpn.cpp''):
<blockquote>
<code>
<pre>
vrpn_Connection *connection;
vrpn_Tracker_Remote *trackerHand;
vrpn_Tracker_Remote *tracker;
vrpn_Tracker_Remote *tracker2;
vrpn_Tracker_Remote *tracker3;
vrpn_Tracker_Remote *tracker4;
</pre>
</code>
</blockquote>
::'''Note:''' We need a ''Tracker_Remote'' object for each constellation we want to track (Hand and each Crazyflie in the Swarm)
:2. Now we create a function to:
:#Register the connection to the Server computer
:#Assign each ''Tracker_Remote'' object to a valid constellation name on the Server computer
:#Link that constellation to a callback (code in ''vrpn.cpp''):
<blockquote>
<code>
<pre>
void vrpn_init(std::string connectionName, void (*callbackHand)(void*, const vrpn_TRACKERCB),
void (*callback)(void*, const vrpn_TRACKERCB), void (*callback2)(void*, const vrpn_TRACKERCB),
void (*callback3)(void*, const vrpn_TRACKERCB), void (*callback4)(void*, const vrpn_TRACKERCB), char *key) {
connection = vrpn_get_connection_by_name(connectionName.c_str());
#if USE_HAND
trackerHand = new vrpn_Tracker_Remote("hand", connection);
#endif
tracker = new vrpn_Tracker_Remote("Crazyflie21", connection);
tracker2 = new vrpn_Tracker_Remote("Crazyflie2", connection);
tracker3 = new vrpn_Tracker_Remote("Crazyflie22", connection);
tracker4 = new vrpn_Tracker_Remote("Crazyflie23", connection);
#if USE_HAND
trackerHand->register_change_handler(0, callbackHand);
#endif
tracker->register_change_handler(0, callback);
tracker2->register_change_handler(0, callback2);
tracker3->register_change_handler(0, callback3);
tracker4->register_change_handler(0, callback4);
usleep(2000);
}
</pre>
</code>
</blockquote>
::'''Note 1:''' We pass in the following as inputs to the function:
::*''string connectionName'' is the '''IP address''' of the Computer running the Camera System
::*A callback pointer for each constellation we want to track (These will be established in the [[#Using a Callback|Using a Callback]] section)
::'''Note 2:''' Notice the names of each ''tracker'' '''match the names of the constellations''' in the Camera System Software (shown below):
::[[Image:TrackingToolsCrazyflieConstellationZeroing.png|800px]]
----
<center> '''Main Directory''' </center>
<center> [[Crazyflie Swarm|Crazyflie Swarm Home]] | [[PC Client Software]] | [[USB Radio]] | [[Firmware]] | [[FAQ]] </center>
<center> '''Modifications Directory''' </center>
<center> [[Controller]] | [[Logging]] | [[Keyboard Commands]] | [[USB Radio#Changing Radio Channel|Changing Radio Channel]] | [[Flight Modes]] | [[Callbacks]] | [[Adding a Crazyflie]] | [[Firmware]] </center>
040fb27438f015cc7329480c744788fb59e0c197
148
146
2016-07-27T19:02:03Z
Jnoronha
3
Added full callback example
wikitext
text/x-wiki
A callback is a segment of code that will run only when a certain condition is satisfied. For the Swarm Platform, the callbacks we use are triggered by the VRPN communications protocol used by the Camera System. Whenever the Client receives a new packet of data from the Camera System the callback will be triggered.
==Registering a Callback==
Before we can do anything we need to set up a callback that executes when new data is present.
:1. Use the VRPN Library to create a ''Connection'' and ''Tracker_Remote'' object pointers (code in ''vrpn.cpp''):
<blockquote>
<code>
<pre>
vrpn_Connection *connection;
vrpn_Tracker_Remote *trackerHand;
vrpn_Tracker_Remote *tracker;
vrpn_Tracker_Remote *tracker2;
vrpn_Tracker_Remote *tracker3;
vrpn_Tracker_Remote *tracker4;
</pre>
</code>
</blockquote>
::'''Note:''' We need a ''Tracker_Remote'' object for each constellation we want to track (Hand and each Crazyflie in the Swarm)
:2. Now we create a function to (code in ''vrpn.cpp''):
:#Register the connection to the Server computer
:#Assign each ''Tracker_Remote'' object to a valid constellation name on the Server computer
:#Link that constellation to a callback
<blockquote>
<code>
<pre>
void vrpn_init(std::string connectionName, void (*callbackHand)(void*, const vrpn_TRACKERCB),
void (*callback)(void*, const vrpn_TRACKERCB), void (*callback2)(void*, const vrpn_TRACKERCB),
void (*callback3)(void*, const vrpn_TRACKERCB), void (*callback4)(void*, const vrpn_TRACKERCB), char *key) {
connection = vrpn_get_connection_by_name(connectionName.c_str());
#if USE_HAND
trackerHand = new vrpn_Tracker_Remote("hand", connection);
#endif
tracker = new vrpn_Tracker_Remote("Crazyflie21", connection);
tracker2 = new vrpn_Tracker_Remote("Crazyflie2", connection);
tracker3 = new vrpn_Tracker_Remote("Crazyflie22", connection);
tracker4 = new vrpn_Tracker_Remote("Crazyflie23", connection);
#if USE_HAND
trackerHand->register_change_handler(0, callbackHand);
#endif
tracker->register_change_handler(0, callback);
tracker2->register_change_handler(0, callback2);
tracker3->register_change_handler(0, callback3);
tracker4->register_change_handler(0, callback4);
usleep(2000);
}
</pre>
</code>
</blockquote>
::'''Note 1:''' We pass in the following as inputs to the function:
::*''string connectionName'' is the "'''IP address:Port'''" of the Computer running the Camera System
::**(You can see the ''VRPN Broadcast Port'' used in the on the middle-right pane called ''Streaming Properties'')
::*A callback pointer for each constellation we want to track (These will be established in the [[:Callbacks#Using a Callback in the Swarm Client|Using a Callback]] section)
::'''Note 2:''' Notice the names of each ''tracker'' '''match the names of the constellations''' in the Camera System Software (shown below):
::[[Image:TrackingToolsCrazyflieConstellationParams.png|800px]]
==Using a Callback in the Swarm Client==
The Swarm Client needs to re-establish the connection to the VRPN server for each test.
===Initializing the Callbacks===
:1. Create the Callback Objects (code in ''eris_vrpn.cpp''):
<blockquote>
<code>
<pre>
void VRPN_CALLBACK handle_hand(void*, const vrpn_TRACKERCB t);
void VRPN_CALLBACK handle_pos(void*, const vrpn_TRACKERCB t); //Old name scheme (represents Callback for Crazyflie1)
void VRPN_CALLBACK handle_Crazyflie2(void*, const vrpn_TRACKERCB t);
void VRPN_CALLBACK handle_Crazyflie3(void*, const vrpn_TRACKERCB t);
void VRPN_CALLBACK handle_Crazyflie4(void*, const vrpn_TRACKERCB t);
</pre>
</code>
</blockquote>
:2. [[:Callbacks#Registering a Callback|Register the connection]] and constellations to the Callbacks (code in ''eris_vrpn.cpp''):
<blockquote>
<code>
<pre>
#if NUM_QUADS == 1
vrpn_init("192.168.0.120:3883", handle_hand, handle_pos, NULL, NULL, NULL, NULL);
#elif NUM_QUADS == 2
vrpn_init("192.168.0.120:3883", handle_hand, handle_pos, handle_Crazyflie2, NULL, NULL, NULL);
#elif NUM_QUADS == 3
vrpn_init("192.168.0.120:3883", handle_hand, handle_pos, handle_Crazyflie2, handle_Crazyflie3, NULL, NULL);
#elif NUM_QUADS == 4
vrpn_init("192.168.0.120:3883", handle_hand, handle_pos, handle_Crazyflie2, handle_Crazyflie3, handle_Crazyflie4, NULL);
#endif
</pre>
</code>
</blockquote>
::'''Note:''' If we don't want to track a certain Crazyflie (i.e. we only want to fly 2 Crazyflies) we can just pass <code>NULL</code> into the init function for the callbacks we don't care about.
===Trigger a Callback===
===Full Callback Example===
Below is a full Callback example for Crazyflie1:
<blockquote>
<code>
<pre>
#if NUM_QUADS >= 1
void VRPN_CALLBACK handle_pos(void*, const vrpn_TRACKERCB t) {
//cout << "First Callback" << endl;
if(vrpnPacketBackup1 < 2) //If VRPN Buffer does NOT have old packets stored up, run main code
{
loopTime1Start = cflieCopter1->currentTime() - initTime1;
loopTime1Delta = loopTime1Start - loopTime1Prev; //Calculates time difference between each loop start
loopTime1Prev = loopTime1Start;
vrpnPacketTime1 = t.msg_time.tv_sec + (t.msg_time.tv_usec / 1000000.0);
vrpnPacketDelta1 = vrpnPacketTime1 - vrpnPacketTime1Prev; //Calculates time between VRPN Data Packets (almost always 0.01 sec)
vrpnPacketTime1Prev = vrpnPacketTime1;
vrpnPacketBackup1 = ceil(loopTime1Delta/vrpnPacketDelta1); //Calculates estimated # of packets built up in VRPN buffer.
controllerSetAllDt(&pidCtrl1, vrpnPacketDelta1); //Variable dt for controller based on time between packets | vrpnPacketDelta1
#if NUM_QUADS == 2
cflieCopter2->cheat_process_packets();
#elif NUM_QUADS == 3
cflieCopter3->cheat_process_packets();
#elif NUM_QUADS == 4
cflieCopter2->cheat_process_packets();
#endif
crRadio1->clearPackets(); //Clears the USB Radio Buffer before switching Radio channels
crRadio1->setChannel( cflieCopter1->radioChannel() );
frameCount++;
// Get the euler angles
q_vec_type euler;
q_to_euler(euler, t.quat);
xPosition1 = t.pos[0];
yPosition1 = t.pos[1]; //Stores X, Y, and Z Position for use in other Callbacks (external)
zPosition1 = -t.pos[2] + 0.05;
#if USE_PRINTOUT
cout << "PID Radio 1" << endl << endl;
#endif
#if 0 //Old way of storing Camera Data (most of it was unnecessary) UNUSED
cfliePitch = cflieCopter1->pitch();
cflieRoll = cflieCopter1->roll();
cflieYaw = cflieCopter1->yaw();
cflieThrust = cflieCopter1->thrust();
/* Legend for Camera Data Packet
* Position
* x t.pos[0]
* y t.pos[1]
* z t.pos[2]
*
* Orientation
* yaw euler[0] Rotation
* pitch euler[1] East-West movement
* roll euler[2] North-South movement
* Euler's range goes from -pi : +pi
*/
QUAD quad;
quad.vrpnNow = 0;
vrpn_data_t *vrpnData;
vrpnData = (vrpn_data_t*) malloc(sizeof(vrpn_data_t));
vrpnData->usec = t.msg_time.tv_sec + (t.msg_time.tv_usec / 1000000.0);
vrpnData->x = t.pos[0];
vrpnData->y = t.pos[1];
vrpnData->z = -t.pos[2] + 0.05; //Higher Altitude = Negative z //Added Offset for floor below camera system origin
vrpnData->yaw = euler[0];
vrpnData->pitch = euler[1];
vrpnData->roll = euler[2];
quad.vrpnPrev = quad.vrpnNow;
if (quad.vrpnNow == 0) {
quad.vrpnPrev = 0;
quad.vrpnTime0 = vrpnData->usec;
quad.vrpnNow = vrpnData->usec;
} else {
quad.vrpnNow = vrpnData->usec - quad.vrpnTime0;
}
#endif //END UNUSED
//==============YAW CORRECTION========================= (IMPORTANT!!!: YAW CONTROLLER INPUT IS INVERTED IN simple.cpp FILE***)
camYawDeg1 = -(euler[0] * 57.2958); //Getting Camera Yaw (Converts From Radians TO Degrees)
quadYaw1 = cflieCopter1->yaw(); //Getting Crazyflie Yaw
if (frameCount == 50) {
if (camYawDeg1 < 0.0)
camYawDeg1Off = camYawDeg1 + 360.0; //Converts from +-180 to full 360 degree form
else
camYawDeg1Off = camYawDeg1;
if(quadYaw1 < 0.0)
quadYaw1Off = quadYaw1 + 360.0;
else
quadYaw1Off = quadYaw1;
yawDifference1 = quadYaw1Off - camYawDeg1Off;
cout << "Yaw1 Offset Taken: " << yawDifference1 << endl;
}
correctedYaw1 = camYawDeg1 + yawDifference1;
if(correctedYaw1 > 180.0)
correctedYaw1 -= 360.0;
else if(correctedYaw1 < -180.0)
correctedYaw1 += 360.0;
//===============END YAW CORRECTION=========================
#if USE_PRINTOUT
cout << "X: " << t.pos[0] << endl;
cout << "Y: " << t.pos[1] << endl;
cout << "Z: " << -t.pos[2] + 0.05 << endl;
// cout << "Quad Yaw: " << cflieCopter1->yaw() << endl;
// cout << "Camera Yaw: " << camYawDeg1 << endl;
// cout << "Yaw Offset: " << yawDifference1 << endl;
// cout << "New Desired Yaw: " << yawDesired1 << endl;
cout << "Frame Count: " << frameCount << endl;
#endif
#if USE_KEYBOARD
if (cflieCopter1->m_enumFlightMode == LANDING_MODE) //Landing Mode
{
//CORRECTS PITCH AND ROLL PID ERRORS TO ACCOUNT FOR QUADS CURRENT YAW DIRECTION
// xError1 = cos(correctedYaw1 / 57.2958)*(xPositionDesired1 - xPosition1) - sin(correctedYaw1 / 57.2958)*(yPositionDesired1 - yPosition1);
// yError1 = sin(correctedYaw1 / 57.2958)*(xPositionDesired1 - xPosition1) + cos(correctedYaw1 / 57.2958)*(yPositionDesired1 - yPosition1);
xError1 = xPositionDesired1 - xPosition1;
yError1 = yPositionDesired1 - yPosition1;
controllerSetXYError(&pidCtrl1, xError1, yError1);
controllerCorrectAttitudePID(&pidCtrl1, t.pos[0], t.pos[1], zPosition1, correctedYaw1,
xPositionDesired1, yPositionDesired1, -0.4, yawDesired1,
&rollControlOutput1, &pitchControlOutput1, &yawControlOutput1,
&thrustControlOutput1);
takeOff1 = 0;
} else if (cflieCopter1->m_enumFlightMode == MIRROR_MODE) { //Acts as Master
xPositionDesired1 = -0.012;
yPositionDesired1 = -0.200;
zPositionDesired1 = 0.75;
if( loopTime1Start - lastTime > 4.0 ) //Creates a 'Step' by changing setpoint every 4 seconds
{
toggle = !toggle;
lastTime = loopTime1Start;
}
if(toggle)
{
xStepPositionError1 = xPositionDesired1 - xPosition1;
yStepPositionError1 = yPositionDesired1 - yPosition1;
controllerSetXYError(&pidCtrl1, xStepPositionError1, yStepPositionError1);
controllerCorrectAttitudePID(&pidCtrl1, t.pos[0], t.pos[1], zPosition1, correctedYaw1,
xPositionDesired1, yPositionDesired1, zPositionDesired1,
yawDesired1, &rollControlOutput1, &pitchControlOutput1,
&yawControlOutput1, &thrustControlOutput1);
}
else //Shifts current x and y setpoint 0.65 meters
{
xStepPositionError1 = (xPositionDesired1 + 0.65) - xPosition1;
yStepPositionError1 = (yPositionDesired1 + 0.65) - yPosition1;
controllerSetXYError(&pidCtrl1, xStepPositionError1, yStepPositionError1);
controllerCorrectAttitudePID(&pidCtrl1, t.pos[0], t.pos[1], zPosition1, correctedYaw1,
xPositionDesired1 + 0.65, yPositionDesired1 + 0.65, zPositionDesired1,
yawDesired1, &rollControlOutput1, &pitchControlOutput1,
&yawControlOutput1, &thrustControlOutput1);
//cout << "Toggled!" << endl;
}
} else if (cflieCopter1->m_enumFlightMode == TAKEOFF_MODE) { //correctedYaw1
//CORRECTS PITCH AND ROLL PID ERRORS TO ACCOUNT FOR QUADS CURRENT YAW DIRECTION
// xError1 = cos(correctedYaw1 / 57.2958)*(xPositionDesired1 - xPosition1) - sin(correctedYaw1 / 57.2958)*(yPositionDesired1 - yPosition1);
// yError1 = sin(correctedYaw1 / 57.2958)*(xPositionDesired1 - xPosition1) + cos(correctedYaw1 / 57.2958)*(yPositionDesired1 - yPosition1);
xError1 = xPositionDesired1 - xPosition1;
yError1 = yPositionDesired1 - yPosition1;
controllerSetXYError(&pidCtrl1, xError1, yError1);
controllerCorrectAttitudePID(&pidCtrl1, t.pos[0], t.pos[1], zPosition1, correctedYaw1,
xPositionDesired1, yPositionDesired1, zPositionDesired1,
yawDesired1, &rollControlOutput1, &pitchControlOutput1,
&yawControlOutput1, &thrustControlOutput1);
}
else if (cflieCopter1->m_enumFlightMode == HAND_MODE) {
//CORRECTS PITCH AND ROLL PID ERRORS TO ACCOUNT FOR QUADS CURRENT YAW DIRECTION
// xError1 = cos(correctedYaw1 / 57.2958)*(xPositionDesired1 - xPosition1) - sin(correctedYaw1 / 57.2958)*(yPositionDesired1 - yPosition1);
// yError1 = sin(correctedYaw1 / 57.2958)*(xPositionDesired1 - xPosition1) + cos(correctedYaw1 / 57.2958)*(yPositionDesired1 - yPosition1);
xError1 = (xPositionHand - 0.5) - xPosition1;
yError1 = (yPositionHand + 0.5) - yPosition1;
controllerSetXYError(&pidCtrl1, xError1, yError1);
controllerCorrectAttitudePID(&pidCtrl1, t.pos[0], t.pos[1], zPosition1, correctedYaw1,
xPositionDesired1, yPositionDesired1, zPositionDesired1,
yawDesired1, &rollControlOutput1, &pitchControlOutput1,
&yawControlOutput1, &thrustControlOutput1);
}
else if(flap){ //Flap Mode (OBSOLETE)
// cflieCopter1->setThrust(20000);
// cflieCopter2->setThrust(20000); //45000 Thrust of Crazyflie2.0 to match Crazyflie1.0
// cflieCopter2->setYaw(90);
// lastTime = cflieCopter2->currentTime();
curTime = cflieCopter2->currentTime();
if( curTime - lastTime > 1.0 )
{
toggle = !toggle;
lastTime = curTime;
}
if( toggle ){
cflieCopter1->setThrust( 20000 );
printf("Low %.3lf ", curTime);
}
else
{
cflieCopter1->setThrust( 40000 );
printf("High %.3lf ", curTime);
}
}
else if(cflieCopter1->m_enumFlightMode == GROUNDED_MODE){
controllerResetAllPID(&pidCtrl1);
rollControlOutput1 = 0;
pitchControlOutput1 = 0;
yawControlOutput1 = 0;
thrustControlOutput1 = 0;
}
else{ //Emergency Case (Should never happen)
controllerResetAllPID(&pidCtrl1);
rollControlOutput1 = 0;
pitchControlOutput1 = 0;
yawControlOutput1 = 0;
thrustControlOutput1 = 0;
}
#else //If keyboard input NOT enabled then just run default Controller
controllerCorrectAttitudePID(&pidCtrl1, t.pos[0], t.pos[1], -t.pos[2], correctedYaw1,
xPositionDesired1, yPositionDesired1, zPositionDesired1,
yawDesired1, &rollControlOutput1, &pitchControlOutput1,
&yawControlOutput1, &thrustControlOutput1);
#endif
RunCrazyflie(crRadio1, cflieCopter1, rollControlOutput1,
pitchControlOutput1, yawControlOutput1, thrustControlOutput1);
#if USE_LOGGING
#if USE_BASIC_LOGGING
fprintf(out1, "%.6f\t\t", cflieCopter1->currentTime() - initTime1 );
fprintf(out1, "%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.6f\t\t%.6f\t\t%.6f\t\t%.6f\t\t%.6f\t\t%.6f\t\t%d\t\t%d",
cflieCopter1->roll(),
cflieCopter1->pitch(),
quadYaw1,
t.pos[0],
t.pos[1],
-t.pos[2],
camYawDeg1,
correctedYaw1,
loopTimeTotal,
loopTimeTotalDelta,
loopTime1,
loopTime1Delta,
vrpnPacketDelta1,
vrpnPacketTime1,
vrpnPacketBackup1,
cflieCopter1->radioRSSI()); //
fprintf(out1, "\n");
#else
//FULL LOGGING ROUTINE (***CAUSES MAJOR BOTTLENECK IN CODE TIMING THE MORE VARIABLES YOU LOG***)
fprintf(out1, "%.6f\t\t", cflieCopter1->currentTime() - initTime1 );
fprintf(out1, "%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.6f\t\t%.6f\t\t%.6f\t\t%.6f\t\t%.6f\t\t%.6f\t\t%d\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%d\t\t%.3f\t\t%.3f\t\t%.3f\t\t%lu\t\t%lu\t\t%lu\t\t%lu\t\t%.3f\t\t%.3f\t\t%.3f",
cflieCopter1->roll(),
cflieCopter1->pitch(),
quadYaw1,
t.pos[0],
t.pos[1],
-t.pos[2],
camYawDeg1,
correctedYaw1,
loopTimeTotal,
loopTimeTotalDelta,
loopTime1,
loopTime1Delta,
vrpnPacketDelta1,
vrpnPacketTime1,
vrpnPacketBackup1,
xPositionDesired1,
yPositionDesired1,
zPositionDesired1,
yawDesired1,
pitchControlOutput1,
rollControlOutput1,
yawControlOutput1,
thrustControlOutput1,
cflieCopter1->radioRSSI(),
euler[0],
euler[1],
euler[2],
cflieCopter1->motor1(),
cflieCopter1->motor2(),
cflieCopter1->motor3(),
cflieCopter1->motor4(),
cflieCopter1->gyroX(),
cflieCopter1->gyroY(),
cflieCopter1->gyroZ()); //
fprintf(out1, "\n");
#endif
#endif
#if 0 //(UNUSED)
if (tcp_client_ON) {
readMulticast(); //(argc < 1 = Listen Mode)
// runTCPClient();
}
#endif
//cout << "PID Radio 2" << endl << endl;
loopTime1End = cflieCopter1->currentTime() - initTime1;
loopTime1 = loopTime1End - loopTime1Start;
}
else if(vrpnPacketBackup1 < 0){ //Failsafe so can't go below 0 (should never happen) | || (vrpnPacketBackup1 > 20)?
vrpnPacketBackup1 = 0;
}
else if(vrpnPacketBackup1 >= 2){
vrpnPacketBackup1 --;
// cout << "VRPN Packet Backup 1 Detected: " << vrpnPacketBackup1 << endl;
}//End Packet Backup If check
} //End Callback 1
</pre>
</code>
</blockquote>
----
<center> '''Main Directory''' </center>
<center> [[Crazyflie Swarm|Crazyflie Swarm Home]] | [[PC Client Software]] | [[USB Radio]] | [[Firmware]] | [[FAQ]] </center>
<center> '''Modifications Directory''' </center>
<center> [[Controller]] | [[Logging]] | [[Keyboard Commands]] | [[USB Radio#Changing Radio Channel|Changing Radio Channel]] | [[Flight Modes]] | [[Callbacks]] | [[Adding a Crazyflie]] | [[Firmware]] </center>
2cd4f630c29ebfca0cece43d09c3c064bdfcf945
149
148
2016-07-27T19:06:14Z
Jnoronha
3
/* Using a Callback in the Swarm Client */ changed the full callback example to a lvl 2 heading
wikitext
text/x-wiki
A callback is a segment of code that will run only when a certain condition is satisfied. For the Swarm Platform, the callbacks we use are triggered by the VRPN communications protocol used by the Camera System. Whenever the Client receives a new packet of data from the Camera System the callback will be triggered.
==Registering a Callback==
Before we can do anything we need to set up a callback that executes when new data is present.
:1. Use the VRPN Library to create a ''Connection'' and ''Tracker_Remote'' object pointers (code in ''vrpn.cpp''):
<blockquote>
<code>
<pre>
vrpn_Connection *connection;
vrpn_Tracker_Remote *trackerHand;
vrpn_Tracker_Remote *tracker;
vrpn_Tracker_Remote *tracker2;
vrpn_Tracker_Remote *tracker3;
vrpn_Tracker_Remote *tracker4;
</pre>
</code>
</blockquote>
::'''Note:''' We need a ''Tracker_Remote'' object for each constellation we want to track (Hand and each Crazyflie in the Swarm)
:2. Now we create a function to (code in ''vrpn.cpp''):
:#Register the connection to the Server computer
:#Assign each ''Tracker_Remote'' object to a valid constellation name on the Server computer
:#Link that constellation to a callback
<blockquote>
<code>
<pre>
void vrpn_init(std::string connectionName, void (*callbackHand)(void*, const vrpn_TRACKERCB),
void (*callback)(void*, const vrpn_TRACKERCB), void (*callback2)(void*, const vrpn_TRACKERCB),
void (*callback3)(void*, const vrpn_TRACKERCB), void (*callback4)(void*, const vrpn_TRACKERCB), char *key) {
connection = vrpn_get_connection_by_name(connectionName.c_str());
#if USE_HAND
trackerHand = new vrpn_Tracker_Remote("hand", connection);
#endif
tracker = new vrpn_Tracker_Remote("Crazyflie21", connection);
tracker2 = new vrpn_Tracker_Remote("Crazyflie2", connection);
tracker3 = new vrpn_Tracker_Remote("Crazyflie22", connection);
tracker4 = new vrpn_Tracker_Remote("Crazyflie23", connection);
#if USE_HAND
trackerHand->register_change_handler(0, callbackHand);
#endif
tracker->register_change_handler(0, callback);
tracker2->register_change_handler(0, callback2);
tracker3->register_change_handler(0, callback3);
tracker4->register_change_handler(0, callback4);
usleep(2000);
}
</pre>
</code>
</blockquote>
::'''Note 1:''' We pass in the following as inputs to the function:
::*''string connectionName'' is the "'''IP address:Port'''" of the Computer running the Camera System
::**(You can see the ''VRPN Broadcast Port'' used in the on the middle-right pane called ''Streaming Properties'')
::*A callback pointer for each constellation we want to track (These will be established in the [[:Callbacks#Using a Callback in the Swarm Client|Using a Callback]] section)
::'''Note 2:''' Notice the names of each ''tracker'' '''match the names of the constellations''' in the Camera System Software (shown below):
::[[Image:TrackingToolsCrazyflieConstellationParams.png|800px]]
==Using a Callback in the Swarm Client==
The Swarm Client needs to re-establish the connection to the VRPN server for each test.
===Initializing the Callbacks===
:1. Create the Callback Objects (code in ''eris_vrpn.cpp''):
<blockquote>
<code>
<pre>
void VRPN_CALLBACK handle_hand(void*, const vrpn_TRACKERCB t);
void VRPN_CALLBACK handle_pos(void*, const vrpn_TRACKERCB t); //Old name scheme (represents Callback for Crazyflie1)
void VRPN_CALLBACK handle_Crazyflie2(void*, const vrpn_TRACKERCB t);
void VRPN_CALLBACK handle_Crazyflie3(void*, const vrpn_TRACKERCB t);
void VRPN_CALLBACK handle_Crazyflie4(void*, const vrpn_TRACKERCB t);
</pre>
</code>
</blockquote>
:2. [[:Callbacks#Registering a Callback|Register the connection]] and constellations to the Callbacks (code in ''eris_vrpn.cpp''):
<blockquote>
<code>
<pre>
#if NUM_QUADS == 1
vrpn_init("192.168.0.120:3883", handle_hand, handle_pos, NULL, NULL, NULL, NULL);
#elif NUM_QUADS == 2
vrpn_init("192.168.0.120:3883", handle_hand, handle_pos, handle_Crazyflie2, NULL, NULL, NULL);
#elif NUM_QUADS == 3
vrpn_init("192.168.0.120:3883", handle_hand, handle_pos, handle_Crazyflie2, handle_Crazyflie3, NULL, NULL);
#elif NUM_QUADS == 4
vrpn_init("192.168.0.120:3883", handle_hand, handle_pos, handle_Crazyflie2, handle_Crazyflie3, handle_Crazyflie4, NULL);
#endif
</pre>
</code>
</blockquote>
::'''Note:''' If we don't want to track a certain Crazyflie (i.e. we only want to fly 2 Crazyflies) we can just pass <code>NULL</code> into the init function for the callbacks we don't care about.
===Trigger a Callback===
:3. Start the mainloop: <code>vrpn_go()</code> (code in ''vrpn.cpp''):
<blockquote>
<code>
<pre>
void vrpn_go() {
int i = 0; //for ending the while loop
while(!i){ //1 replace 'i<20000' when done testing ******
readKeyboard();
nearGround();
#if USE_HAND
updateHand();
#endif
loopTimeTotalStart = cflieCopter1->currentTime() - initTime1;
loopTimeTotalDelta = loopTimeTotalStart - loopTimeTotalPrev;
loopTimeTotalPrev = loopTimeTotalStart;
connection->mainloop();
#if USE_HAND
trackerHand->mainloop();
#endif
tracker->mainloop();
tracker2->mainloop();
tracker3->mainloop();
tracker4->mainloop();
usleep(200); //Was 200
//Testing Routines
//i++;
//nonblock(0);
nonblock(1);
usleep(1);
i = kbhit(); //keyboard hit (state change)
if (i!=0)
{
keystroke_now = fgetc(stdin);
if (keystroke_now == 'q')
i=1;
else{
i=0;
}
//fprintf(stderr,"%d ",i);
}
}//END WHILE
if(keystroke_now == 'q'){
cout << "Program Forced End" << endl;
}
loopTimeTotalEnd = cflieCopter1->currentTime() - initTime1;
loopTimeTotal = loopTimeTotalEnd - loopTimeTotalStart;
} //END VRPN GO
</pre>
</code>
</blockquote>
==Full Callback Example==
Below is a full Callback example for Crazyflie1:
<blockquote>
<code>
<pre>
#if NUM_QUADS >= 1
void VRPN_CALLBACK handle_pos(void*, const vrpn_TRACKERCB t) {
//cout << "First Callback" << endl;
if(vrpnPacketBackup1 < 2) //If VRPN Buffer does NOT have old packets stored up, run main code
{
loopTime1Start = cflieCopter1->currentTime() - initTime1;
loopTime1Delta = loopTime1Start - loopTime1Prev; //Calculates time difference between each loop start
loopTime1Prev = loopTime1Start;
vrpnPacketTime1 = t.msg_time.tv_sec + (t.msg_time.tv_usec / 1000000.0);
vrpnPacketDelta1 = vrpnPacketTime1 - vrpnPacketTime1Prev; //Calculates time between VRPN Data Packets (almost always 0.01 sec)
vrpnPacketTime1Prev = vrpnPacketTime1;
vrpnPacketBackup1 = ceil(loopTime1Delta/vrpnPacketDelta1); //Calculates estimated # of packets built up in VRPN buffer.
controllerSetAllDt(&pidCtrl1, vrpnPacketDelta1); //Variable dt for controller based on time between packets | vrpnPacketDelta1
#if NUM_QUADS == 2
cflieCopter2->cheat_process_packets();
#elif NUM_QUADS == 3
cflieCopter3->cheat_process_packets();
#elif NUM_QUADS == 4
cflieCopter2->cheat_process_packets();
#endif
crRadio1->clearPackets(); //Clears the USB Radio Buffer before switching Radio channels
crRadio1->setChannel( cflieCopter1->radioChannel() );
frameCount++;
// Get the euler angles
q_vec_type euler;
q_to_euler(euler, t.quat);
xPosition1 = t.pos[0];
yPosition1 = t.pos[1]; //Stores X, Y, and Z Position for use in other Callbacks (external)
zPosition1 = -t.pos[2] + 0.05;
#if USE_PRINTOUT
cout << "PID Radio 1" << endl << endl;
#endif
#if 0 //Old way of storing Camera Data (most of it was unnecessary) UNUSED
cfliePitch = cflieCopter1->pitch();
cflieRoll = cflieCopter1->roll();
cflieYaw = cflieCopter1->yaw();
cflieThrust = cflieCopter1->thrust();
/* Legend for Camera Data Packet
* Position
* x t.pos[0]
* y t.pos[1]
* z t.pos[2]
*
* Orientation
* yaw euler[0] Rotation
* pitch euler[1] East-West movement
* roll euler[2] North-South movement
* Euler's range goes from -pi : +pi
*/
QUAD quad;
quad.vrpnNow = 0;
vrpn_data_t *vrpnData;
vrpnData = (vrpn_data_t*) malloc(sizeof(vrpn_data_t));
vrpnData->usec = t.msg_time.tv_sec + (t.msg_time.tv_usec / 1000000.0);
vrpnData->x = t.pos[0];
vrpnData->y = t.pos[1];
vrpnData->z = -t.pos[2] + 0.05; //Higher Altitude = Negative z //Added Offset for floor below camera system origin
vrpnData->yaw = euler[0];
vrpnData->pitch = euler[1];
vrpnData->roll = euler[2];
quad.vrpnPrev = quad.vrpnNow;
if (quad.vrpnNow == 0) {
quad.vrpnPrev = 0;
quad.vrpnTime0 = vrpnData->usec;
quad.vrpnNow = vrpnData->usec;
} else {
quad.vrpnNow = vrpnData->usec - quad.vrpnTime0;
}
#endif //END UNUSED
//==============YAW CORRECTION========================= (IMPORTANT!!!: YAW CONTROLLER INPUT IS INVERTED IN simple.cpp FILE***)
camYawDeg1 = -(euler[0] * 57.2958); //Getting Camera Yaw (Converts From Radians TO Degrees)
quadYaw1 = cflieCopter1->yaw(); //Getting Crazyflie Yaw
if (frameCount == 50) {
if (camYawDeg1 < 0.0)
camYawDeg1Off = camYawDeg1 + 360.0; //Converts from +-180 to full 360 degree form
else
camYawDeg1Off = camYawDeg1;
if(quadYaw1 < 0.0)
quadYaw1Off = quadYaw1 + 360.0;
else
quadYaw1Off = quadYaw1;
yawDifference1 = quadYaw1Off - camYawDeg1Off;
cout << "Yaw1 Offset Taken: " << yawDifference1 << endl;
}
correctedYaw1 = camYawDeg1 + yawDifference1;
if(correctedYaw1 > 180.0)
correctedYaw1 -= 360.0;
else if(correctedYaw1 < -180.0)
correctedYaw1 += 360.0;
//===============END YAW CORRECTION=========================
#if USE_PRINTOUT
cout << "X: " << t.pos[0] << endl;
cout << "Y: " << t.pos[1] << endl;
cout << "Z: " << -t.pos[2] + 0.05 << endl;
// cout << "Quad Yaw: " << cflieCopter1->yaw() << endl;
// cout << "Camera Yaw: " << camYawDeg1 << endl;
// cout << "Yaw Offset: " << yawDifference1 << endl;
// cout << "New Desired Yaw: " << yawDesired1 << endl;
cout << "Frame Count: " << frameCount << endl;
#endif
#if USE_KEYBOARD
if (cflieCopter1->m_enumFlightMode == LANDING_MODE) //Landing Mode
{
//CORRECTS PITCH AND ROLL PID ERRORS TO ACCOUNT FOR QUADS CURRENT YAW DIRECTION
// xError1 = cos(correctedYaw1 / 57.2958)*(xPositionDesired1 - xPosition1) - sin(correctedYaw1 / 57.2958)*(yPositionDesired1 - yPosition1);
// yError1 = sin(correctedYaw1 / 57.2958)*(xPositionDesired1 - xPosition1) + cos(correctedYaw1 / 57.2958)*(yPositionDesired1 - yPosition1);
xError1 = xPositionDesired1 - xPosition1;
yError1 = yPositionDesired1 - yPosition1;
controllerSetXYError(&pidCtrl1, xError1, yError1);
controllerCorrectAttitudePID(&pidCtrl1, t.pos[0], t.pos[1], zPosition1, correctedYaw1,
xPositionDesired1, yPositionDesired1, -0.4, yawDesired1,
&rollControlOutput1, &pitchControlOutput1, &yawControlOutput1,
&thrustControlOutput1);
takeOff1 = 0;
} else if (cflieCopter1->m_enumFlightMode == MIRROR_MODE) { //Acts as Master
xPositionDesired1 = -0.012;
yPositionDesired1 = -0.200;
zPositionDesired1 = 0.75;
if( loopTime1Start - lastTime > 4.0 ) //Creates a 'Step' by changing setpoint every 4 seconds
{
toggle = !toggle;
lastTime = loopTime1Start;
}
if(toggle)
{
xStepPositionError1 = xPositionDesired1 - xPosition1;
yStepPositionError1 = yPositionDesired1 - yPosition1;
controllerSetXYError(&pidCtrl1, xStepPositionError1, yStepPositionError1);
controllerCorrectAttitudePID(&pidCtrl1, t.pos[0], t.pos[1], zPosition1, correctedYaw1,
xPositionDesired1, yPositionDesired1, zPositionDesired1,
yawDesired1, &rollControlOutput1, &pitchControlOutput1,
&yawControlOutput1, &thrustControlOutput1);
}
else //Shifts current x and y setpoint 0.65 meters
{
xStepPositionError1 = (xPositionDesired1 + 0.65) - xPosition1;
yStepPositionError1 = (yPositionDesired1 + 0.65) - yPosition1;
controllerSetXYError(&pidCtrl1, xStepPositionError1, yStepPositionError1);
controllerCorrectAttitudePID(&pidCtrl1, t.pos[0], t.pos[1], zPosition1, correctedYaw1,
xPositionDesired1 + 0.65, yPositionDesired1 + 0.65, zPositionDesired1,
yawDesired1, &rollControlOutput1, &pitchControlOutput1,
&yawControlOutput1, &thrustControlOutput1);
//cout << "Toggled!" << endl;
}
} else if (cflieCopter1->m_enumFlightMode == TAKEOFF_MODE) { //correctedYaw1
//CORRECTS PITCH AND ROLL PID ERRORS TO ACCOUNT FOR QUADS CURRENT YAW DIRECTION
// xError1 = cos(correctedYaw1 / 57.2958)*(xPositionDesired1 - xPosition1) - sin(correctedYaw1 / 57.2958)*(yPositionDesired1 - yPosition1);
// yError1 = sin(correctedYaw1 / 57.2958)*(xPositionDesired1 - xPosition1) + cos(correctedYaw1 / 57.2958)*(yPositionDesired1 - yPosition1);
xError1 = xPositionDesired1 - xPosition1;
yError1 = yPositionDesired1 - yPosition1;
controllerSetXYError(&pidCtrl1, xError1, yError1);
controllerCorrectAttitudePID(&pidCtrl1, t.pos[0], t.pos[1], zPosition1, correctedYaw1,
xPositionDesired1, yPositionDesired1, zPositionDesired1,
yawDesired1, &rollControlOutput1, &pitchControlOutput1,
&yawControlOutput1, &thrustControlOutput1);
}
else if (cflieCopter1->m_enumFlightMode == HAND_MODE) {
//CORRECTS PITCH AND ROLL PID ERRORS TO ACCOUNT FOR QUADS CURRENT YAW DIRECTION
// xError1 = cos(correctedYaw1 / 57.2958)*(xPositionDesired1 - xPosition1) - sin(correctedYaw1 / 57.2958)*(yPositionDesired1 - yPosition1);
// yError1 = sin(correctedYaw1 / 57.2958)*(xPositionDesired1 - xPosition1) + cos(correctedYaw1 / 57.2958)*(yPositionDesired1 - yPosition1);
xError1 = (xPositionHand - 0.5) - xPosition1;
yError1 = (yPositionHand + 0.5) - yPosition1;
controllerSetXYError(&pidCtrl1, xError1, yError1);
controllerCorrectAttitudePID(&pidCtrl1, t.pos[0], t.pos[1], zPosition1, correctedYaw1,
xPositionDesired1, yPositionDesired1, zPositionDesired1,
yawDesired1, &rollControlOutput1, &pitchControlOutput1,
&yawControlOutput1, &thrustControlOutput1);
}
else if(flap){ //Flap Mode (OBSOLETE)
// cflieCopter1->setThrust(20000);
// cflieCopter2->setThrust(20000); //45000 Thrust of Crazyflie2.0 to match Crazyflie1.0
// cflieCopter2->setYaw(90);
// lastTime = cflieCopter2->currentTime();
curTime = cflieCopter2->currentTime();
if( curTime - lastTime > 1.0 )
{
toggle = !toggle;
lastTime = curTime;
}
if( toggle ){
cflieCopter1->setThrust( 20000 );
printf("Low %.3lf ", curTime);
}
else
{
cflieCopter1->setThrust( 40000 );
printf("High %.3lf ", curTime);
}
}
else if(cflieCopter1->m_enumFlightMode == GROUNDED_MODE){
controllerResetAllPID(&pidCtrl1);
rollControlOutput1 = 0;
pitchControlOutput1 = 0;
yawControlOutput1 = 0;
thrustControlOutput1 = 0;
}
else{ //Emergency Case (Should never happen)
controllerResetAllPID(&pidCtrl1);
rollControlOutput1 = 0;
pitchControlOutput1 = 0;
yawControlOutput1 = 0;
thrustControlOutput1 = 0;
}
#else //If keyboard input NOT enabled then just run default Controller
controllerCorrectAttitudePID(&pidCtrl1, t.pos[0], t.pos[1], -t.pos[2], correctedYaw1,
xPositionDesired1, yPositionDesired1, zPositionDesired1,
yawDesired1, &rollControlOutput1, &pitchControlOutput1,
&yawControlOutput1, &thrustControlOutput1);
#endif
RunCrazyflie(crRadio1, cflieCopter1, rollControlOutput1,
pitchControlOutput1, yawControlOutput1, thrustControlOutput1);
#if USE_LOGGING
#if USE_BASIC_LOGGING
fprintf(out1, "%.6f\t\t", cflieCopter1->currentTime() - initTime1 );
fprintf(out1, "%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.6f\t\t%.6f\t\t%.6f\t\t%.6f\t\t%.6f\t\t%.6f\t\t%d\t\t%d",
cflieCopter1->roll(),
cflieCopter1->pitch(),
quadYaw1,
t.pos[0],
t.pos[1],
-t.pos[2],
camYawDeg1,
correctedYaw1,
loopTimeTotal,
loopTimeTotalDelta,
loopTime1,
loopTime1Delta,
vrpnPacketDelta1,
vrpnPacketTime1,
vrpnPacketBackup1,
cflieCopter1->radioRSSI()); //
fprintf(out1, "\n");
#else
//FULL LOGGING ROUTINE (***CAUSES MAJOR BOTTLENECK IN CODE TIMING THE MORE VARIABLES YOU LOG***)
fprintf(out1, "%.6f\t\t", cflieCopter1->currentTime() - initTime1 );
fprintf(out1, "%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.6f\t\t%.6f\t\t%.6f\t\t%.6f\t\t%.6f\t\t%.6f\t\t%d\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%d\t\t%.3f\t\t%.3f\t\t%.3f\t\t%lu\t\t%lu\t\t%lu\t\t%lu\t\t%.3f\t\t%.3f\t\t%.3f",
cflieCopter1->roll(),
cflieCopter1->pitch(),
quadYaw1,
t.pos[0],
t.pos[1],
-t.pos[2],
camYawDeg1,
correctedYaw1,
loopTimeTotal,
loopTimeTotalDelta,
loopTime1,
loopTime1Delta,
vrpnPacketDelta1,
vrpnPacketTime1,
vrpnPacketBackup1,
xPositionDesired1,
yPositionDesired1,
zPositionDesired1,
yawDesired1,
pitchControlOutput1,
rollControlOutput1,
yawControlOutput1,
thrustControlOutput1,
cflieCopter1->radioRSSI(),
euler[0],
euler[1],
euler[2],
cflieCopter1->motor1(),
cflieCopter1->motor2(),
cflieCopter1->motor3(),
cflieCopter1->motor4(),
cflieCopter1->gyroX(),
cflieCopter1->gyroY(),
cflieCopter1->gyroZ()); //
fprintf(out1, "\n");
#endif
#endif
#if 0 //(UNUSED)
if (tcp_client_ON) {
readMulticast(); //(argc < 1 = Listen Mode)
// runTCPClient();
}
#endif
//cout << "PID Radio 2" << endl << endl;
loopTime1End = cflieCopter1->currentTime() - initTime1;
loopTime1 = loopTime1End - loopTime1Start;
}
else if(vrpnPacketBackup1 < 0){ //Failsafe so can't go below 0 (should never happen) | || (vrpnPacketBackup1 > 20)?
vrpnPacketBackup1 = 0;
}
else if(vrpnPacketBackup1 >= 2){
vrpnPacketBackup1 --;
// cout << "VRPN Packet Backup 1 Detected: " << vrpnPacketBackup1 << endl;
}//End Packet Backup If check
} //End Callback 1
</pre>
</code>
</blockquote>
----
<center> '''Main Directory''' </center>
<center> [[Crazyflie Swarm|Crazyflie Swarm Home]] | [[PC Client Software]] | [[USB Radio]] | [[Firmware]] | [[FAQ]] </center>
<center> '''Modifications Directory''' </center>
<center> [[Controller]] | [[Logging]] | [[Keyboard Commands]] | [[USB Radio#Changing Radio Channel|Changing Radio Channel]] | [[Flight Modes]] | [[Callbacks]] | [[Adding a Crazyflie]] | [[Firmware]] </center>
b4be15ef64d405a0347a7dd9781751fbaad47b88
150
149
2016-07-27T19:27:18Z
Jnoronha
3
/* Using a Callback in the Swarm Client */ added flowchart and finished
wikitext
text/x-wiki
A callback is a segment of code that will run only when a certain condition is satisfied. For the Swarm Platform, the callbacks we use are triggered by the VRPN communications protocol used by the Camera System. Whenever the Client receives a new packet of data from the Camera System the callback will be triggered.
==Registering a Callback==
Before we can do anything we need to set up a callback that executes when new data is present.
:1. Use the VRPN Library to create a ''Connection'' and ''Tracker_Remote'' object pointers (code in ''vrpn.cpp''):
<blockquote>
<code>
<pre>
vrpn_Connection *connection;
vrpn_Tracker_Remote *trackerHand;
vrpn_Tracker_Remote *tracker;
vrpn_Tracker_Remote *tracker2;
vrpn_Tracker_Remote *tracker3;
vrpn_Tracker_Remote *tracker4;
</pre>
</code>
</blockquote>
::'''Note:''' We need a ''Tracker_Remote'' object for each constellation we want to track (Hand and each Crazyflie in the Swarm)
:2. Now we create a function to (code in ''vrpn.cpp''):
:#Register the connection to the Server computer
:#Assign each ''Tracker_Remote'' object to a valid constellation name on the Server computer
:#Link that constellation to a callback
<blockquote>
<code>
<pre>
void vrpn_init(std::string connectionName, void (*callbackHand)(void*, const vrpn_TRACKERCB),
void (*callback)(void*, const vrpn_TRACKERCB), void (*callback2)(void*, const vrpn_TRACKERCB),
void (*callback3)(void*, const vrpn_TRACKERCB), void (*callback4)(void*, const vrpn_TRACKERCB), char *key) {
connection = vrpn_get_connection_by_name(connectionName.c_str());
#if USE_HAND
trackerHand = new vrpn_Tracker_Remote("hand", connection);
#endif
tracker = new vrpn_Tracker_Remote("Crazyflie21", connection);
tracker2 = new vrpn_Tracker_Remote("Crazyflie2", connection);
tracker3 = new vrpn_Tracker_Remote("Crazyflie22", connection);
tracker4 = new vrpn_Tracker_Remote("Crazyflie23", connection);
#if USE_HAND
trackerHand->register_change_handler(0, callbackHand);
#endif
tracker->register_change_handler(0, callback);
tracker2->register_change_handler(0, callback2);
tracker3->register_change_handler(0, callback3);
tracker4->register_change_handler(0, callback4);
usleep(2000);
}
</pre>
</code>
</blockquote>
::'''Note 1:''' We pass in the following as inputs to the function:
::*''string connectionName'' is the "'''IP address:Port'''" of the Computer running the Camera System
::**(You can see the ''VRPN Broadcast Port'' used in the on the middle-right pane called ''Streaming Properties'')
::*A callback pointer for each constellation we want to track (These will be established in the [[:Callbacks#Using a Callback in the Swarm Client|Using a Callback]] section)
::'''Note 2:''' Notice the names of each ''tracker'' '''match the names of the constellations''' in the Camera System Software (shown below):
::[[Image:TrackingToolsCrazyflieConstellationParams.png|800px]]
==Using a Callback in the Swarm Client==
The Swarm Client needs to re-establish the connection to the VRPN server for each test.
===Initializing the Callbacks===
:1. Create the Callback Objects (code in ''eris_vrpn.cpp''):
<blockquote>
<code>
<pre>
void VRPN_CALLBACK handle_hand(void*, const vrpn_TRACKERCB t);
void VRPN_CALLBACK handle_pos(void*, const vrpn_TRACKERCB t); //Old name scheme (represents Callback for Crazyflie1)
void VRPN_CALLBACK handle_Crazyflie2(void*, const vrpn_TRACKERCB t);
void VRPN_CALLBACK handle_Crazyflie3(void*, const vrpn_TRACKERCB t);
void VRPN_CALLBACK handle_Crazyflie4(void*, const vrpn_TRACKERCB t);
</pre>
</code>
</blockquote>
:2. [[:Callbacks#Registering a Callback|Register the connection]] and constellations to the Callbacks (code in ''eris_vrpn.cpp''):
<blockquote>
<code>
<pre>
#if NUM_QUADS == 1
vrpn_init("192.168.0.120:3883", handle_hand, handle_pos, NULL, NULL, NULL, NULL);
#elif NUM_QUADS == 2
vrpn_init("192.168.0.120:3883", handle_hand, handle_pos, handle_Crazyflie2, NULL, NULL, NULL);
#elif NUM_QUADS == 3
vrpn_init("192.168.0.120:3883", handle_hand, handle_pos, handle_Crazyflie2, handle_Crazyflie3, NULL, NULL);
#elif NUM_QUADS == 4
vrpn_init("192.168.0.120:3883", handle_hand, handle_pos, handle_Crazyflie2, handle_Crazyflie3, handle_Crazyflie4, NULL);
#endif
</pre>
</code>
</blockquote>
::'''Note:''' If we don't want to track a certain Crazyflie (i.e. we only want to fly 2 Crazyflies) we can just pass <code>NULL</code> into the init function for the callbacks we don't care about.
===Calling a Callback===
:3. Start the mainloop: <code>vrpn_go()</code> (code in ''vrpn.cpp'') (function called in ''eris_vrpn.cpp'')
::*A flowchart of the vrpn_go() function:
[[Image:VRPNGO.png|500px]]
::*Full vrpn_go() code (code in ''vrpn.cpp''):
<blockquote>
<code>
<pre>
void vrpn_go() {
int i = 0; //for ending the while loop
while(!i){
readKeyboard(); //Triggers actions based on key value read
nearGround();
#if USE_HAND
updateHand(); //Checks for Valid Hand Gestures
#endif
//Calculates Total Loop Timing
loopTimeTotalStart = cflieCopter1->currentTime() - initTime1;
loopTimeTotalDelta = loopTimeTotalStart - loopTimeTotalPrev;
loopTimeTotalPrev = loopTimeTotalStart;
connection->mainloop(); //Pings the Server Connection to see if still alive
#if USE_HAND
trackerHand->mainloop(); //Checks if Hand constellation has new data (runs callback if true)
#endif
tracker->mainloop(); //IMPORTANT: Checks if Crazyflie1 constellation has new data (runs callback if true)
tracker2->mainloop(); //Same...
tracker3->mainloop();
tracker4->mainloop();
usleep(200); //Was 200
nonblock(1);
usleep(1);
i = kbhit(); //keyboard hit (state change)
if (i!=0)
{
keystroke_now = fgetc(stdin); //Stores key value pressed
if (keystroke_now == 'q')
i=1;
else{
i=0;
}
//fprintf(stderr,"%d ",i);
}
}//END WHILE
if(keystroke_now == 'q'){
cout << "Program Forced End" << endl;
}
loopTimeTotalEnd = cflieCopter1->currentTime() - initTime1;
loopTimeTotal = loopTimeTotalEnd - loopTimeTotalStart;
} //END VRPN GO
</pre>
</code>
</blockquote>
::'''Note:''' The most important part of this is the <code>tracker->mainloop();</code> functions. These functions are what calls the Callback if there is new data waiting!!
::You can see an example of the code that is executed whenever the [[:Callbacks#Full Callback Example|callback is triggered]]
==Full Callback Example==
Below is a full Callback example for Crazyflie1:
<blockquote>
<code>
<pre>
#if NUM_QUADS >= 1
void VRPN_CALLBACK handle_pos(void*, const vrpn_TRACKERCB t) {
//cout << "First Callback" << endl;
if(vrpnPacketBackup1 < 2) //If VRPN Buffer does NOT have old packets stored up, run main code
{
loopTime1Start = cflieCopter1->currentTime() - initTime1;
loopTime1Delta = loopTime1Start - loopTime1Prev; //Calculates time difference between each loop start
loopTime1Prev = loopTime1Start;
vrpnPacketTime1 = t.msg_time.tv_sec + (t.msg_time.tv_usec / 1000000.0);
vrpnPacketDelta1 = vrpnPacketTime1 - vrpnPacketTime1Prev; //Calculates time between VRPN Data Packets (almost always 0.01 sec)
vrpnPacketTime1Prev = vrpnPacketTime1;
vrpnPacketBackup1 = ceil(loopTime1Delta/vrpnPacketDelta1); //Calculates estimated # of packets built up in VRPN buffer.
controllerSetAllDt(&pidCtrl1, vrpnPacketDelta1); //Variable dt for controller based on time between packets | vrpnPacketDelta1
#if NUM_QUADS == 2
cflieCopter2->cheat_process_packets();
#elif NUM_QUADS == 3
cflieCopter3->cheat_process_packets();
#elif NUM_QUADS == 4
cflieCopter2->cheat_process_packets();
#endif
crRadio1->clearPackets(); //Clears the USB Radio Buffer before switching Radio channels
crRadio1->setChannel( cflieCopter1->radioChannel() );
frameCount++;
// Get the euler angles
q_vec_type euler;
q_to_euler(euler, t.quat);
xPosition1 = t.pos[0];
yPosition1 = t.pos[1]; //Stores X, Y, and Z Position for use in other Callbacks (external)
zPosition1 = -t.pos[2] + 0.05;
#if USE_PRINTOUT
cout << "PID Radio 1" << endl << endl;
#endif
#if 0 //Old way of storing Camera Data (most of it was unnecessary) UNUSED
cfliePitch = cflieCopter1->pitch();
cflieRoll = cflieCopter1->roll();
cflieYaw = cflieCopter1->yaw();
cflieThrust = cflieCopter1->thrust();
/* Legend for Camera Data Packet
* Position
* x t.pos[0]
* y t.pos[1]
* z t.pos[2]
*
* Orientation
* yaw euler[0] Rotation
* pitch euler[1] East-West movement
* roll euler[2] North-South movement
* Euler's range goes from -pi : +pi
*/
QUAD quad;
quad.vrpnNow = 0;
vrpn_data_t *vrpnData;
vrpnData = (vrpn_data_t*) malloc(sizeof(vrpn_data_t));
vrpnData->usec = t.msg_time.tv_sec + (t.msg_time.tv_usec / 1000000.0);
vrpnData->x = t.pos[0];
vrpnData->y = t.pos[1];
vrpnData->z = -t.pos[2] + 0.05; //Higher Altitude = Negative z //Added Offset for floor below camera system origin
vrpnData->yaw = euler[0];
vrpnData->pitch = euler[1];
vrpnData->roll = euler[2];
quad.vrpnPrev = quad.vrpnNow;
if (quad.vrpnNow == 0) {
quad.vrpnPrev = 0;
quad.vrpnTime0 = vrpnData->usec;
quad.vrpnNow = vrpnData->usec;
} else {
quad.vrpnNow = vrpnData->usec - quad.vrpnTime0;
}
#endif //END UNUSED
//==============YAW CORRECTION========================= (IMPORTANT!!!: YAW CONTROLLER INPUT IS INVERTED IN simple.cpp FILE***)
camYawDeg1 = -(euler[0] * 57.2958); //Getting Camera Yaw (Converts From Radians TO Degrees)
quadYaw1 = cflieCopter1->yaw(); //Getting Crazyflie Yaw
if (frameCount == 50) {
if (camYawDeg1 < 0.0)
camYawDeg1Off = camYawDeg1 + 360.0; //Converts from +-180 to full 360 degree form
else
camYawDeg1Off = camYawDeg1;
if(quadYaw1 < 0.0)
quadYaw1Off = quadYaw1 + 360.0;
else
quadYaw1Off = quadYaw1;
yawDifference1 = quadYaw1Off - camYawDeg1Off;
cout << "Yaw1 Offset Taken: " << yawDifference1 << endl;
}
correctedYaw1 = camYawDeg1 + yawDifference1;
if(correctedYaw1 > 180.0)
correctedYaw1 -= 360.0;
else if(correctedYaw1 < -180.0)
correctedYaw1 += 360.0;
//===============END YAW CORRECTION=========================
#if USE_PRINTOUT
cout << "X: " << t.pos[0] << endl;
cout << "Y: " << t.pos[1] << endl;
cout << "Z: " << -t.pos[2] + 0.05 << endl;
// cout << "Quad Yaw: " << cflieCopter1->yaw() << endl;
// cout << "Camera Yaw: " << camYawDeg1 << endl;
// cout << "Yaw Offset: " << yawDifference1 << endl;
// cout << "New Desired Yaw: " << yawDesired1 << endl;
cout << "Frame Count: " << frameCount << endl;
#endif
#if USE_KEYBOARD
if (cflieCopter1->m_enumFlightMode == LANDING_MODE) //Landing Mode
{
//CORRECTS PITCH AND ROLL PID ERRORS TO ACCOUNT FOR QUADS CURRENT YAW DIRECTION
// xError1 = cos(correctedYaw1 / 57.2958)*(xPositionDesired1 - xPosition1) - sin(correctedYaw1 / 57.2958)*(yPositionDesired1 - yPosition1);
// yError1 = sin(correctedYaw1 / 57.2958)*(xPositionDesired1 - xPosition1) + cos(correctedYaw1 / 57.2958)*(yPositionDesired1 - yPosition1);
xError1 = xPositionDesired1 - xPosition1;
yError1 = yPositionDesired1 - yPosition1;
controllerSetXYError(&pidCtrl1, xError1, yError1);
controllerCorrectAttitudePID(&pidCtrl1, t.pos[0], t.pos[1], zPosition1, correctedYaw1,
xPositionDesired1, yPositionDesired1, -0.4, yawDesired1,
&rollControlOutput1, &pitchControlOutput1, &yawControlOutput1,
&thrustControlOutput1);
takeOff1 = 0;
} else if (cflieCopter1->m_enumFlightMode == MIRROR_MODE) { //Acts as Master
xPositionDesired1 = -0.012;
yPositionDesired1 = -0.200;
zPositionDesired1 = 0.75;
if( loopTime1Start - lastTime > 4.0 ) //Creates a 'Step' by changing setpoint every 4 seconds
{
toggle = !toggle;
lastTime = loopTime1Start;
}
if(toggle)
{
xStepPositionError1 = xPositionDesired1 - xPosition1;
yStepPositionError1 = yPositionDesired1 - yPosition1;
controllerSetXYError(&pidCtrl1, xStepPositionError1, yStepPositionError1);
controllerCorrectAttitudePID(&pidCtrl1, t.pos[0], t.pos[1], zPosition1, correctedYaw1,
xPositionDesired1, yPositionDesired1, zPositionDesired1,
yawDesired1, &rollControlOutput1, &pitchControlOutput1,
&yawControlOutput1, &thrustControlOutput1);
}
else //Shifts current x and y setpoint 0.65 meters
{
xStepPositionError1 = (xPositionDesired1 + 0.65) - xPosition1;
yStepPositionError1 = (yPositionDesired1 + 0.65) - yPosition1;
controllerSetXYError(&pidCtrl1, xStepPositionError1, yStepPositionError1);
controllerCorrectAttitudePID(&pidCtrl1, t.pos[0], t.pos[1], zPosition1, correctedYaw1,
xPositionDesired1 + 0.65, yPositionDesired1 + 0.65, zPositionDesired1,
yawDesired1, &rollControlOutput1, &pitchControlOutput1,
&yawControlOutput1, &thrustControlOutput1);
//cout << "Toggled!" << endl;
}
} else if (cflieCopter1->m_enumFlightMode == TAKEOFF_MODE) { //correctedYaw1
//CORRECTS PITCH AND ROLL PID ERRORS TO ACCOUNT FOR QUADS CURRENT YAW DIRECTION
// xError1 = cos(correctedYaw1 / 57.2958)*(xPositionDesired1 - xPosition1) - sin(correctedYaw1 / 57.2958)*(yPositionDesired1 - yPosition1);
// yError1 = sin(correctedYaw1 / 57.2958)*(xPositionDesired1 - xPosition1) + cos(correctedYaw1 / 57.2958)*(yPositionDesired1 - yPosition1);
xError1 = xPositionDesired1 - xPosition1;
yError1 = yPositionDesired1 - yPosition1;
controllerSetXYError(&pidCtrl1, xError1, yError1);
controllerCorrectAttitudePID(&pidCtrl1, t.pos[0], t.pos[1], zPosition1, correctedYaw1,
xPositionDesired1, yPositionDesired1, zPositionDesired1,
yawDesired1, &rollControlOutput1, &pitchControlOutput1,
&yawControlOutput1, &thrustControlOutput1);
}
else if (cflieCopter1->m_enumFlightMode == HAND_MODE) {
//CORRECTS PITCH AND ROLL PID ERRORS TO ACCOUNT FOR QUADS CURRENT YAW DIRECTION
// xError1 = cos(correctedYaw1 / 57.2958)*(xPositionDesired1 - xPosition1) - sin(correctedYaw1 / 57.2958)*(yPositionDesired1 - yPosition1);
// yError1 = sin(correctedYaw1 / 57.2958)*(xPositionDesired1 - xPosition1) + cos(correctedYaw1 / 57.2958)*(yPositionDesired1 - yPosition1);
xError1 = (xPositionHand - 0.5) - xPosition1;
yError1 = (yPositionHand + 0.5) - yPosition1;
controllerSetXYError(&pidCtrl1, xError1, yError1);
controllerCorrectAttitudePID(&pidCtrl1, t.pos[0], t.pos[1], zPosition1, correctedYaw1,
xPositionDesired1, yPositionDesired1, zPositionDesired1,
yawDesired1, &rollControlOutput1, &pitchControlOutput1,
&yawControlOutput1, &thrustControlOutput1);
}
else if(flap){ //Flap Mode (OBSOLETE)
// cflieCopter1->setThrust(20000);
// cflieCopter2->setThrust(20000); //45000 Thrust of Crazyflie2.0 to match Crazyflie1.0
// cflieCopter2->setYaw(90);
// lastTime = cflieCopter2->currentTime();
curTime = cflieCopter2->currentTime();
if( curTime - lastTime > 1.0 )
{
toggle = !toggle;
lastTime = curTime;
}
if( toggle ){
cflieCopter1->setThrust( 20000 );
printf("Low %.3lf ", curTime);
}
else
{
cflieCopter1->setThrust( 40000 );
printf("High %.3lf ", curTime);
}
}
else if(cflieCopter1->m_enumFlightMode == GROUNDED_MODE){
controllerResetAllPID(&pidCtrl1);
rollControlOutput1 = 0;
pitchControlOutput1 = 0;
yawControlOutput1 = 0;
thrustControlOutput1 = 0;
}
else{ //Emergency Case (Should never happen)
controllerResetAllPID(&pidCtrl1);
rollControlOutput1 = 0;
pitchControlOutput1 = 0;
yawControlOutput1 = 0;
thrustControlOutput1 = 0;
}
#else //If keyboard input NOT enabled then just run default Controller
controllerCorrectAttitudePID(&pidCtrl1, t.pos[0], t.pos[1], -t.pos[2], correctedYaw1,
xPositionDesired1, yPositionDesired1, zPositionDesired1,
yawDesired1, &rollControlOutput1, &pitchControlOutput1,
&yawControlOutput1, &thrustControlOutput1);
#endif
RunCrazyflie(crRadio1, cflieCopter1, rollControlOutput1,
pitchControlOutput1, yawControlOutput1, thrustControlOutput1);
#if USE_LOGGING
#if USE_BASIC_LOGGING
fprintf(out1, "%.6f\t\t", cflieCopter1->currentTime() - initTime1 );
fprintf(out1, "%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.6f\t\t%.6f\t\t%.6f\t\t%.6f\t\t%.6f\t\t%.6f\t\t%d\t\t%d",
cflieCopter1->roll(),
cflieCopter1->pitch(),
quadYaw1,
t.pos[0],
t.pos[1],
-t.pos[2],
camYawDeg1,
correctedYaw1,
loopTimeTotal,
loopTimeTotalDelta,
loopTime1,
loopTime1Delta,
vrpnPacketDelta1,
vrpnPacketTime1,
vrpnPacketBackup1,
cflieCopter1->radioRSSI()); //
fprintf(out1, "\n");
#else
//FULL LOGGING ROUTINE (***CAUSES MAJOR BOTTLENECK IN CODE TIMING THE MORE VARIABLES YOU LOG***)
fprintf(out1, "%.6f\t\t", cflieCopter1->currentTime() - initTime1 );
fprintf(out1, "%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.6f\t\t%.6f\t\t%.6f\t\t%.6f\t\t%.6f\t\t%.6f\t\t%d\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%d\t\t%.3f\t\t%.3f\t\t%.3f\t\t%lu\t\t%lu\t\t%lu\t\t%lu\t\t%.3f\t\t%.3f\t\t%.3f",
cflieCopter1->roll(),
cflieCopter1->pitch(),
quadYaw1,
t.pos[0],
t.pos[1],
-t.pos[2],
camYawDeg1,
correctedYaw1,
loopTimeTotal,
loopTimeTotalDelta,
loopTime1,
loopTime1Delta,
vrpnPacketDelta1,
vrpnPacketTime1,
vrpnPacketBackup1,
xPositionDesired1,
yPositionDesired1,
zPositionDesired1,
yawDesired1,
pitchControlOutput1,
rollControlOutput1,
yawControlOutput1,
thrustControlOutput1,
cflieCopter1->radioRSSI(),
euler[0],
euler[1],
euler[2],
cflieCopter1->motor1(),
cflieCopter1->motor2(),
cflieCopter1->motor3(),
cflieCopter1->motor4(),
cflieCopter1->gyroX(),
cflieCopter1->gyroY(),
cflieCopter1->gyroZ()); //
fprintf(out1, "\n");
#endif
#endif
#if 0 //(UNUSED)
if (tcp_client_ON) {
readMulticast(); //(argc < 1 = Listen Mode)
// runTCPClient();
}
#endif
//cout << "PID Radio 2" << endl << endl;
loopTime1End = cflieCopter1->currentTime() - initTime1;
loopTime1 = loopTime1End - loopTime1Start;
}
else if(vrpnPacketBackup1 < 0){ //Failsafe so can't go below 0 (should never happen) | || (vrpnPacketBackup1 > 20)?
vrpnPacketBackup1 = 0;
}
else if(vrpnPacketBackup1 >= 2){
vrpnPacketBackup1 --;
// cout << "VRPN Packet Backup 1 Detected: " << vrpnPacketBackup1 << endl;
}//End Packet Backup If check
} //End Callback 1
</pre>
</code>
</blockquote>
----
<center> '''Main Directory''' </center>
<center> [[Crazyflie Swarm|Crazyflie Swarm Home]] | [[PC Client Software]] | [[USB Radio]] | [[Firmware]] | [[FAQ]] </center>
<center> '''Modifications Directory''' </center>
<center> [[Controller]] | [[Logging]] | [[Keyboard Commands]] | [[USB Radio#Changing Radio Channel|Changing Radio Channel]] | [[Flight Modes]] | [[Callbacks]] | [[Adding a Crazyflie]] | [[Firmware]] </center>
d4dd58adeb0de4562492ffe7f2c558ce5f84ab0d
File:TrackingToolsCrazyflieConstellationParams.png
6
45
147
2016-07-27T18:20:51Z
Jnoronha
3
Camera System Software with Crazyflie and Hand Constellations and Server Port Info
wikitext
text/x-wiki
Camera System Software with Crazyflie and Hand Constellations and Server Port Info
432e585d1f7446ecf7d98fcc6976aaeedbcd9b9e
Callbacks
0
44
151
150
2016-07-27T19:31:02Z
Jnoronha
3
/* Registering a Callback */ added flowchart for init function
wikitext
text/x-wiki
A callback is a segment of code that will run only when a certain condition is satisfied. For the Swarm Platform, the callbacks we use are triggered by the VRPN communications protocol used by the Camera System. Whenever the Client receives a new packet of data from the Camera System the callback will be triggered.
==Registering a Callback==
Before we can do anything we need to set up a callback that executes when new data is present.
:1. Use the VRPN Library to create a ''Connection'' and ''Tracker_Remote'' object pointers (code in ''vrpn.cpp''):
<blockquote>
<code>
<pre>
vrpn_Connection *connection;
vrpn_Tracker_Remote *trackerHand;
vrpn_Tracker_Remote *tracker;
vrpn_Tracker_Remote *tracker2;
vrpn_Tracker_Remote *tracker3;
vrpn_Tracker_Remote *tracker4;
</pre>
</code>
</blockquote>
::'''Note:''' We need a ''Tracker_Remote'' object for each constellation we want to track (Hand and each Crazyflie in the Swarm)
:2. Now we create a function to (code in ''vrpn.cpp''):
:#Register the connection to the Server computer
:#Assign each ''Tracker_Remote'' object to a valid constellation name on the Server computer
:#Link that constellation to a callback
:*Flowchart of the Init process
[[Image:VRPN_INIT.png]]
:*Full code
<blockquote>
<code>
<pre>
void vrpn_init(std::string connectionName, void (*callbackHand)(void*, const vrpn_TRACKERCB),
void (*callback)(void*, const vrpn_TRACKERCB), void (*callback2)(void*, const vrpn_TRACKERCB),
void (*callback3)(void*, const vrpn_TRACKERCB), void (*callback4)(void*, const vrpn_TRACKERCB), char *key) {
connection = vrpn_get_connection_by_name(connectionName.c_str());
#if USE_HAND
trackerHand = new vrpn_Tracker_Remote("hand", connection);
#endif
tracker = new vrpn_Tracker_Remote("Crazyflie21", connection);
tracker2 = new vrpn_Tracker_Remote("Crazyflie2", connection);
tracker3 = new vrpn_Tracker_Remote("Crazyflie22", connection);
tracker4 = new vrpn_Tracker_Remote("Crazyflie23", connection);
#if USE_HAND
trackerHand->register_change_handler(0, callbackHand);
#endif
tracker->register_change_handler(0, callback);
tracker2->register_change_handler(0, callback2);
tracker3->register_change_handler(0, callback3);
tracker4->register_change_handler(0, callback4);
usleep(2000);
}
</pre>
</code>
</blockquote>
::'''Note 1:''' We pass in the following as inputs to the function:
::*''string connectionName'' is the "'''IP address:Port'''" of the Computer running the Camera System
::**(You can see the ''VRPN Broadcast Port'' used in the on the middle-right pane called ''Streaming Properties'')
::*A callback pointer for each constellation we want to track (These will be established in the [[:Callbacks#Using a Callback in the Swarm Client|Using a Callback]] section)
::'''Note 2:''' Notice the names of each ''tracker'' '''match the names of the constellations''' in the Camera System Software (shown below):
::[[Image:TrackingToolsCrazyflieConstellationParams.png|800px]]
==Using a Callback in the Swarm Client==
The Swarm Client needs to re-establish the connection to the VRPN server for each test.
===Initializing the Callbacks===
:1. Create the Callback Objects (code in ''eris_vrpn.cpp''):
<blockquote>
<code>
<pre>
void VRPN_CALLBACK handle_hand(void*, const vrpn_TRACKERCB t);
void VRPN_CALLBACK handle_pos(void*, const vrpn_TRACKERCB t); //Old name scheme (represents Callback for Crazyflie1)
void VRPN_CALLBACK handle_Crazyflie2(void*, const vrpn_TRACKERCB t);
void VRPN_CALLBACK handle_Crazyflie3(void*, const vrpn_TRACKERCB t);
void VRPN_CALLBACK handle_Crazyflie4(void*, const vrpn_TRACKERCB t);
</pre>
</code>
</blockquote>
:2. [[:Callbacks#Registering a Callback|Register the connection]] and constellations to the Callbacks (code in ''eris_vrpn.cpp''):
<blockquote>
<code>
<pre>
#if NUM_QUADS == 1
vrpn_init("192.168.0.120:3883", handle_hand, handle_pos, NULL, NULL, NULL, NULL);
#elif NUM_QUADS == 2
vrpn_init("192.168.0.120:3883", handle_hand, handle_pos, handle_Crazyflie2, NULL, NULL, NULL);
#elif NUM_QUADS == 3
vrpn_init("192.168.0.120:3883", handle_hand, handle_pos, handle_Crazyflie2, handle_Crazyflie3, NULL, NULL);
#elif NUM_QUADS == 4
vrpn_init("192.168.0.120:3883", handle_hand, handle_pos, handle_Crazyflie2, handle_Crazyflie3, handle_Crazyflie4, NULL);
#endif
</pre>
</code>
</blockquote>
::'''Note:''' If we don't want to track a certain Crazyflie (i.e. we only want to fly 2 Crazyflies) we can just pass <code>NULL</code> into the init function for the callbacks we don't care about.
===Calling a Callback===
:3. Start the mainloop: <code>vrpn_go()</code> (code in ''vrpn.cpp'') (function called in ''eris_vrpn.cpp'')
::*A flowchart of the vrpn_go() function:
[[Image:VRPNGO.png|500px]]
::*Full vrpn_go() code (code in ''vrpn.cpp''):
<blockquote>
<code>
<pre>
void vrpn_go() {
int i = 0; //for ending the while loop
while(!i){
readKeyboard(); //Triggers actions based on key value read
nearGround();
#if USE_HAND
updateHand(); //Checks for Valid Hand Gestures
#endif
//Calculates Total Loop Timing
loopTimeTotalStart = cflieCopter1->currentTime() - initTime1;
loopTimeTotalDelta = loopTimeTotalStart - loopTimeTotalPrev;
loopTimeTotalPrev = loopTimeTotalStart;
connection->mainloop(); //Pings the Server Connection to see if still alive
#if USE_HAND
trackerHand->mainloop(); //Checks if Hand constellation has new data (runs callback if true)
#endif
tracker->mainloop(); //IMPORTANT: Checks if Crazyflie1 constellation has new data (runs callback if true)
tracker2->mainloop(); //Same...
tracker3->mainloop();
tracker4->mainloop();
usleep(200); //Was 200
nonblock(1);
usleep(1);
i = kbhit(); //keyboard hit (state change)
if (i!=0)
{
keystroke_now = fgetc(stdin); //Stores key value pressed
if (keystroke_now == 'q')
i=1;
else{
i=0;
}
//fprintf(stderr,"%d ",i);
}
}//END WHILE
if(keystroke_now == 'q'){
cout << "Program Forced End" << endl;
}
loopTimeTotalEnd = cflieCopter1->currentTime() - initTime1;
loopTimeTotal = loopTimeTotalEnd - loopTimeTotalStart;
} //END VRPN GO
</pre>
</code>
</blockquote>
::'''Note:''' The most important part of this is the <code>tracker->mainloop();</code> functions. These functions are what calls the Callback if there is new data waiting!!
::You can see an example of the code that is executed whenever the [[:Callbacks#Full Callback Example|callback is triggered]]
==Full Callback Example==
Below is a full Callback example for Crazyflie1:
<blockquote>
<code>
<pre>
#if NUM_QUADS >= 1
void VRPN_CALLBACK handle_pos(void*, const vrpn_TRACKERCB t) {
//cout << "First Callback" << endl;
if(vrpnPacketBackup1 < 2) //If VRPN Buffer does NOT have old packets stored up, run main code
{
loopTime1Start = cflieCopter1->currentTime() - initTime1;
loopTime1Delta = loopTime1Start - loopTime1Prev; //Calculates time difference between each loop start
loopTime1Prev = loopTime1Start;
vrpnPacketTime1 = t.msg_time.tv_sec + (t.msg_time.tv_usec / 1000000.0);
vrpnPacketDelta1 = vrpnPacketTime1 - vrpnPacketTime1Prev; //Calculates time between VRPN Data Packets (almost always 0.01 sec)
vrpnPacketTime1Prev = vrpnPacketTime1;
vrpnPacketBackup1 = ceil(loopTime1Delta/vrpnPacketDelta1); //Calculates estimated # of packets built up in VRPN buffer.
controllerSetAllDt(&pidCtrl1, vrpnPacketDelta1); //Variable dt for controller based on time between packets | vrpnPacketDelta1
#if NUM_QUADS == 2
cflieCopter2->cheat_process_packets();
#elif NUM_QUADS == 3
cflieCopter3->cheat_process_packets();
#elif NUM_QUADS == 4
cflieCopter2->cheat_process_packets();
#endif
crRadio1->clearPackets(); //Clears the USB Radio Buffer before switching Radio channels
crRadio1->setChannel( cflieCopter1->radioChannel() );
frameCount++;
// Get the euler angles
q_vec_type euler;
q_to_euler(euler, t.quat);
xPosition1 = t.pos[0];
yPosition1 = t.pos[1]; //Stores X, Y, and Z Position for use in other Callbacks (external)
zPosition1 = -t.pos[2] + 0.05;
#if USE_PRINTOUT
cout << "PID Radio 1" << endl << endl;
#endif
#if 0 //Old way of storing Camera Data (most of it was unnecessary) UNUSED
cfliePitch = cflieCopter1->pitch();
cflieRoll = cflieCopter1->roll();
cflieYaw = cflieCopter1->yaw();
cflieThrust = cflieCopter1->thrust();
/* Legend for Camera Data Packet
* Position
* x t.pos[0]
* y t.pos[1]
* z t.pos[2]
*
* Orientation
* yaw euler[0] Rotation
* pitch euler[1] East-West movement
* roll euler[2] North-South movement
* Euler's range goes from -pi : +pi
*/
QUAD quad;
quad.vrpnNow = 0;
vrpn_data_t *vrpnData;
vrpnData = (vrpn_data_t*) malloc(sizeof(vrpn_data_t));
vrpnData->usec = t.msg_time.tv_sec + (t.msg_time.tv_usec / 1000000.0);
vrpnData->x = t.pos[0];
vrpnData->y = t.pos[1];
vrpnData->z = -t.pos[2] + 0.05; //Higher Altitude = Negative z //Added Offset for floor below camera system origin
vrpnData->yaw = euler[0];
vrpnData->pitch = euler[1];
vrpnData->roll = euler[2];
quad.vrpnPrev = quad.vrpnNow;
if (quad.vrpnNow == 0) {
quad.vrpnPrev = 0;
quad.vrpnTime0 = vrpnData->usec;
quad.vrpnNow = vrpnData->usec;
} else {
quad.vrpnNow = vrpnData->usec - quad.vrpnTime0;
}
#endif //END UNUSED
//==============YAW CORRECTION========================= (IMPORTANT!!!: YAW CONTROLLER INPUT IS INVERTED IN simple.cpp FILE***)
camYawDeg1 = -(euler[0] * 57.2958); //Getting Camera Yaw (Converts From Radians TO Degrees)
quadYaw1 = cflieCopter1->yaw(); //Getting Crazyflie Yaw
if (frameCount == 50) {
if (camYawDeg1 < 0.0)
camYawDeg1Off = camYawDeg1 + 360.0; //Converts from +-180 to full 360 degree form
else
camYawDeg1Off = camYawDeg1;
if(quadYaw1 < 0.0)
quadYaw1Off = quadYaw1 + 360.0;
else
quadYaw1Off = quadYaw1;
yawDifference1 = quadYaw1Off - camYawDeg1Off;
cout << "Yaw1 Offset Taken: " << yawDifference1 << endl;
}
correctedYaw1 = camYawDeg1 + yawDifference1;
if(correctedYaw1 > 180.0)
correctedYaw1 -= 360.0;
else if(correctedYaw1 < -180.0)
correctedYaw1 += 360.0;
//===============END YAW CORRECTION=========================
#if USE_PRINTOUT
cout << "X: " << t.pos[0] << endl;
cout << "Y: " << t.pos[1] << endl;
cout << "Z: " << -t.pos[2] + 0.05 << endl;
// cout << "Quad Yaw: " << cflieCopter1->yaw() << endl;
// cout << "Camera Yaw: " << camYawDeg1 << endl;
// cout << "Yaw Offset: " << yawDifference1 << endl;
// cout << "New Desired Yaw: " << yawDesired1 << endl;
cout << "Frame Count: " << frameCount << endl;
#endif
#if USE_KEYBOARD
if (cflieCopter1->m_enumFlightMode == LANDING_MODE) //Landing Mode
{
//CORRECTS PITCH AND ROLL PID ERRORS TO ACCOUNT FOR QUADS CURRENT YAW DIRECTION
// xError1 = cos(correctedYaw1 / 57.2958)*(xPositionDesired1 - xPosition1) - sin(correctedYaw1 / 57.2958)*(yPositionDesired1 - yPosition1);
// yError1 = sin(correctedYaw1 / 57.2958)*(xPositionDesired1 - xPosition1) + cos(correctedYaw1 / 57.2958)*(yPositionDesired1 - yPosition1);
xError1 = xPositionDesired1 - xPosition1;
yError1 = yPositionDesired1 - yPosition1;
controllerSetXYError(&pidCtrl1, xError1, yError1);
controllerCorrectAttitudePID(&pidCtrl1, t.pos[0], t.pos[1], zPosition1, correctedYaw1,
xPositionDesired1, yPositionDesired1, -0.4, yawDesired1,
&rollControlOutput1, &pitchControlOutput1, &yawControlOutput1,
&thrustControlOutput1);
takeOff1 = 0;
} else if (cflieCopter1->m_enumFlightMode == MIRROR_MODE) { //Acts as Master
xPositionDesired1 = -0.012;
yPositionDesired1 = -0.200;
zPositionDesired1 = 0.75;
if( loopTime1Start - lastTime > 4.0 ) //Creates a 'Step' by changing setpoint every 4 seconds
{
toggle = !toggle;
lastTime = loopTime1Start;
}
if(toggle)
{
xStepPositionError1 = xPositionDesired1 - xPosition1;
yStepPositionError1 = yPositionDesired1 - yPosition1;
controllerSetXYError(&pidCtrl1, xStepPositionError1, yStepPositionError1);
controllerCorrectAttitudePID(&pidCtrl1, t.pos[0], t.pos[1], zPosition1, correctedYaw1,
xPositionDesired1, yPositionDesired1, zPositionDesired1,
yawDesired1, &rollControlOutput1, &pitchControlOutput1,
&yawControlOutput1, &thrustControlOutput1);
}
else //Shifts current x and y setpoint 0.65 meters
{
xStepPositionError1 = (xPositionDesired1 + 0.65) - xPosition1;
yStepPositionError1 = (yPositionDesired1 + 0.65) - yPosition1;
controllerSetXYError(&pidCtrl1, xStepPositionError1, yStepPositionError1);
controllerCorrectAttitudePID(&pidCtrl1, t.pos[0], t.pos[1], zPosition1, correctedYaw1,
xPositionDesired1 + 0.65, yPositionDesired1 + 0.65, zPositionDesired1,
yawDesired1, &rollControlOutput1, &pitchControlOutput1,
&yawControlOutput1, &thrustControlOutput1);
//cout << "Toggled!" << endl;
}
} else if (cflieCopter1->m_enumFlightMode == TAKEOFF_MODE) { //correctedYaw1
//CORRECTS PITCH AND ROLL PID ERRORS TO ACCOUNT FOR QUADS CURRENT YAW DIRECTION
// xError1 = cos(correctedYaw1 / 57.2958)*(xPositionDesired1 - xPosition1) - sin(correctedYaw1 / 57.2958)*(yPositionDesired1 - yPosition1);
// yError1 = sin(correctedYaw1 / 57.2958)*(xPositionDesired1 - xPosition1) + cos(correctedYaw1 / 57.2958)*(yPositionDesired1 - yPosition1);
xError1 = xPositionDesired1 - xPosition1;
yError1 = yPositionDesired1 - yPosition1;
controllerSetXYError(&pidCtrl1, xError1, yError1);
controllerCorrectAttitudePID(&pidCtrl1, t.pos[0], t.pos[1], zPosition1, correctedYaw1,
xPositionDesired1, yPositionDesired1, zPositionDesired1,
yawDesired1, &rollControlOutput1, &pitchControlOutput1,
&yawControlOutput1, &thrustControlOutput1);
}
else if (cflieCopter1->m_enumFlightMode == HAND_MODE) {
//CORRECTS PITCH AND ROLL PID ERRORS TO ACCOUNT FOR QUADS CURRENT YAW DIRECTION
// xError1 = cos(correctedYaw1 / 57.2958)*(xPositionDesired1 - xPosition1) - sin(correctedYaw1 / 57.2958)*(yPositionDesired1 - yPosition1);
// yError1 = sin(correctedYaw1 / 57.2958)*(xPositionDesired1 - xPosition1) + cos(correctedYaw1 / 57.2958)*(yPositionDesired1 - yPosition1);
xError1 = (xPositionHand - 0.5) - xPosition1;
yError1 = (yPositionHand + 0.5) - yPosition1;
controllerSetXYError(&pidCtrl1, xError1, yError1);
controllerCorrectAttitudePID(&pidCtrl1, t.pos[0], t.pos[1], zPosition1, correctedYaw1,
xPositionDesired1, yPositionDesired1, zPositionDesired1,
yawDesired1, &rollControlOutput1, &pitchControlOutput1,
&yawControlOutput1, &thrustControlOutput1);
}
else if(flap){ //Flap Mode (OBSOLETE)
// cflieCopter1->setThrust(20000);
// cflieCopter2->setThrust(20000); //45000 Thrust of Crazyflie2.0 to match Crazyflie1.0
// cflieCopter2->setYaw(90);
// lastTime = cflieCopter2->currentTime();
curTime = cflieCopter2->currentTime();
if( curTime - lastTime > 1.0 )
{
toggle = !toggle;
lastTime = curTime;
}
if( toggle ){
cflieCopter1->setThrust( 20000 );
printf("Low %.3lf ", curTime);
}
else
{
cflieCopter1->setThrust( 40000 );
printf("High %.3lf ", curTime);
}
}
else if(cflieCopter1->m_enumFlightMode == GROUNDED_MODE){
controllerResetAllPID(&pidCtrl1);
rollControlOutput1 = 0;
pitchControlOutput1 = 0;
yawControlOutput1 = 0;
thrustControlOutput1 = 0;
}
else{ //Emergency Case (Should never happen)
controllerResetAllPID(&pidCtrl1);
rollControlOutput1 = 0;
pitchControlOutput1 = 0;
yawControlOutput1 = 0;
thrustControlOutput1 = 0;
}
#else //If keyboard input NOT enabled then just run default Controller
controllerCorrectAttitudePID(&pidCtrl1, t.pos[0], t.pos[1], -t.pos[2], correctedYaw1,
xPositionDesired1, yPositionDesired1, zPositionDesired1,
yawDesired1, &rollControlOutput1, &pitchControlOutput1,
&yawControlOutput1, &thrustControlOutput1);
#endif
RunCrazyflie(crRadio1, cflieCopter1, rollControlOutput1,
pitchControlOutput1, yawControlOutput1, thrustControlOutput1);
#if USE_LOGGING
#if USE_BASIC_LOGGING
fprintf(out1, "%.6f\t\t", cflieCopter1->currentTime() - initTime1 );
fprintf(out1, "%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.6f\t\t%.6f\t\t%.6f\t\t%.6f\t\t%.6f\t\t%.6f\t\t%d\t\t%d",
cflieCopter1->roll(),
cflieCopter1->pitch(),
quadYaw1,
t.pos[0],
t.pos[1],
-t.pos[2],
camYawDeg1,
correctedYaw1,
loopTimeTotal,
loopTimeTotalDelta,
loopTime1,
loopTime1Delta,
vrpnPacketDelta1,
vrpnPacketTime1,
vrpnPacketBackup1,
cflieCopter1->radioRSSI()); //
fprintf(out1, "\n");
#else
//FULL LOGGING ROUTINE (***CAUSES MAJOR BOTTLENECK IN CODE TIMING THE MORE VARIABLES YOU LOG***)
fprintf(out1, "%.6f\t\t", cflieCopter1->currentTime() - initTime1 );
fprintf(out1, "%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.6f\t\t%.6f\t\t%.6f\t\t%.6f\t\t%.6f\t\t%.6f\t\t%d\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%d\t\t%.3f\t\t%.3f\t\t%.3f\t\t%lu\t\t%lu\t\t%lu\t\t%lu\t\t%.3f\t\t%.3f\t\t%.3f",
cflieCopter1->roll(),
cflieCopter1->pitch(),
quadYaw1,
t.pos[0],
t.pos[1],
-t.pos[2],
camYawDeg1,
correctedYaw1,
loopTimeTotal,
loopTimeTotalDelta,
loopTime1,
loopTime1Delta,
vrpnPacketDelta1,
vrpnPacketTime1,
vrpnPacketBackup1,
xPositionDesired1,
yPositionDesired1,
zPositionDesired1,
yawDesired1,
pitchControlOutput1,
rollControlOutput1,
yawControlOutput1,
thrustControlOutput1,
cflieCopter1->radioRSSI(),
euler[0],
euler[1],
euler[2],
cflieCopter1->motor1(),
cflieCopter1->motor2(),
cflieCopter1->motor3(),
cflieCopter1->motor4(),
cflieCopter1->gyroX(),
cflieCopter1->gyroY(),
cflieCopter1->gyroZ()); //
fprintf(out1, "\n");
#endif
#endif
#if 0 //(UNUSED)
if (tcp_client_ON) {
readMulticast(); //(argc < 1 = Listen Mode)
// runTCPClient();
}
#endif
//cout << "PID Radio 2" << endl << endl;
loopTime1End = cflieCopter1->currentTime() - initTime1;
loopTime1 = loopTime1End - loopTime1Start;
}
else if(vrpnPacketBackup1 < 0){ //Failsafe so can't go below 0 (should never happen) | || (vrpnPacketBackup1 > 20)?
vrpnPacketBackup1 = 0;
}
else if(vrpnPacketBackup1 >= 2){
vrpnPacketBackup1 --;
// cout << "VRPN Packet Backup 1 Detected: " << vrpnPacketBackup1 << endl;
}//End Packet Backup If check
} //End Callback 1
</pre>
</code>
</blockquote>
----
<center> '''Main Directory''' </center>
<center> [[Crazyflie Swarm|Crazyflie Swarm Home]] | [[PC Client Software]] | [[USB Radio]] | [[Firmware]] | [[FAQ]] </center>
<center> '''Modifications Directory''' </center>
<center> [[Controller]] | [[Logging]] | [[Keyboard Commands]] | [[USB Radio#Changing Radio Channel|Changing Radio Channel]] | [[Flight Modes]] | [[Callbacks]] | [[Adding a Crazyflie]] | [[Firmware]] </center>
e5d7948494835bae2de18d105e8c32e9281a7137
152
151
2016-07-27T19:37:24Z
Jnoronha
3
added link to vrpn and camera system section
wikitext
text/x-wiki
A callback is a segment of code that will run only when a certain condition is satisfied. For the Swarm Platform, the callbacks we use are triggered by the VRPN communications protocol used by the Camera System. Whenever the Client receives a new packet of data from the Camera System the callback will be triggered.
See [[Camera System and VRPN|VRPN and the Camera System]] if you want more detail on those systems before you start.
==Registering a Callback==
Before we can do anything we need to set up a callback that executes when new data is present.
:1. Use the VRPN Library to create a ''Connection'' and ''Tracker_Remote'' object pointers (code in ''vrpn.cpp''):
<blockquote>
<code>
<pre>
vrpn_Connection *connection;
vrpn_Tracker_Remote *trackerHand;
vrpn_Tracker_Remote *tracker;
vrpn_Tracker_Remote *tracker2;
vrpn_Tracker_Remote *tracker3;
vrpn_Tracker_Remote *tracker4;
</pre>
</code>
</blockquote>
::'''Note:''' We need a ''Tracker_Remote'' object for each constellation we want to track (Hand and each Crazyflie in the Swarm)
:2. Now we create a function to (code in ''vrpn.cpp''):
:#Register the connection to the Server computer
:#Assign each ''Tracker_Remote'' object to a valid constellation name on the Server computer
:#Link that constellation to a callback
:*Flowchart of the Init process
[[Image:VRPN_INIT.png]]
:*Full code
<blockquote>
<code>
<pre>
void vrpn_init(std::string connectionName, void (*callbackHand)(void*, const vrpn_TRACKERCB),
void (*callback)(void*, const vrpn_TRACKERCB), void (*callback2)(void*, const vrpn_TRACKERCB),
void (*callback3)(void*, const vrpn_TRACKERCB), void (*callback4)(void*, const vrpn_TRACKERCB), char *key) {
connection = vrpn_get_connection_by_name(connectionName.c_str());
#if USE_HAND
trackerHand = new vrpn_Tracker_Remote("hand", connection);
#endif
tracker = new vrpn_Tracker_Remote("Crazyflie21", connection);
tracker2 = new vrpn_Tracker_Remote("Crazyflie2", connection);
tracker3 = new vrpn_Tracker_Remote("Crazyflie22", connection);
tracker4 = new vrpn_Tracker_Remote("Crazyflie23", connection);
#if USE_HAND
trackerHand->register_change_handler(0, callbackHand);
#endif
tracker->register_change_handler(0, callback);
tracker2->register_change_handler(0, callback2);
tracker3->register_change_handler(0, callback3);
tracker4->register_change_handler(0, callback4);
usleep(2000);
}
</pre>
</code>
</blockquote>
::'''Note 1:''' We pass in the following as inputs to the function:
::*''string connectionName'' is the "'''IP address:Port'''" of the Computer running the Camera System
::**(You can see the ''VRPN Broadcast Port'' used in the on the middle-right pane called ''Streaming Properties'')
::*A callback pointer for each constellation we want to track (These will be established in the [[:Callbacks#Using a Callback in the Swarm Client|Using a Callback]] section)
::'''Note 2:''' Notice the names of each ''tracker'' '''match the names of the constellations''' in the Camera System Software (shown below):
::[[Image:TrackingToolsCrazyflieConstellationParams.png|800px]]
==Using a Callback in the Swarm Client==
The Swarm Client needs to re-establish the connection to the VRPN server for each test.
===Initializing the Callbacks===
:1. Create the Callback Objects (code in ''eris_vrpn.cpp''):
<blockquote>
<code>
<pre>
void VRPN_CALLBACK handle_hand(void*, const vrpn_TRACKERCB t);
void VRPN_CALLBACK handle_pos(void*, const vrpn_TRACKERCB t); //Old name scheme (represents Callback for Crazyflie1)
void VRPN_CALLBACK handle_Crazyflie2(void*, const vrpn_TRACKERCB t);
void VRPN_CALLBACK handle_Crazyflie3(void*, const vrpn_TRACKERCB t);
void VRPN_CALLBACK handle_Crazyflie4(void*, const vrpn_TRACKERCB t);
</pre>
</code>
</blockquote>
:2. [[:Callbacks#Registering a Callback|Register the connection]] and constellations to the Callbacks (code in ''eris_vrpn.cpp''):
<blockquote>
<code>
<pre>
#if NUM_QUADS == 1
vrpn_init("192.168.0.120:3883", handle_hand, handle_pos, NULL, NULL, NULL, NULL);
#elif NUM_QUADS == 2
vrpn_init("192.168.0.120:3883", handle_hand, handle_pos, handle_Crazyflie2, NULL, NULL, NULL);
#elif NUM_QUADS == 3
vrpn_init("192.168.0.120:3883", handle_hand, handle_pos, handle_Crazyflie2, handle_Crazyflie3, NULL, NULL);
#elif NUM_QUADS == 4
vrpn_init("192.168.0.120:3883", handle_hand, handle_pos, handle_Crazyflie2, handle_Crazyflie3, handle_Crazyflie4, NULL);
#endif
</pre>
</code>
</blockquote>
::'''Note:''' If we don't want to track a certain Crazyflie (i.e. we only want to fly 2 Crazyflies) we can just pass <code>NULL</code> into the init function for the callbacks we don't care about.
===Calling a Callback===
:3. Start the mainloop: <code>vrpn_go()</code> (code in ''vrpn.cpp'') (function called in ''eris_vrpn.cpp'')
::*A flowchart of the vrpn_go() function:
[[Image:VRPNGO.png|500px]]
::*Full vrpn_go() code (code in ''vrpn.cpp''):
<blockquote>
<code>
<pre>
void vrpn_go() {
int i = 0; //for ending the while loop
while(!i){
readKeyboard(); //Triggers actions based on key value read
nearGround();
#if USE_HAND
updateHand(); //Checks for Valid Hand Gestures
#endif
//Calculates Total Loop Timing
loopTimeTotalStart = cflieCopter1->currentTime() - initTime1;
loopTimeTotalDelta = loopTimeTotalStart - loopTimeTotalPrev;
loopTimeTotalPrev = loopTimeTotalStart;
connection->mainloop(); //Pings the Server Connection to see if still alive
#if USE_HAND
trackerHand->mainloop(); //Checks if Hand constellation has new data (runs callback if true)
#endif
tracker->mainloop(); //IMPORTANT: Checks if Crazyflie1 constellation has new data (runs callback if true)
tracker2->mainloop(); //Same...
tracker3->mainloop();
tracker4->mainloop();
usleep(200); //Was 200
nonblock(1);
usleep(1);
i = kbhit(); //keyboard hit (state change)
if (i!=0)
{
keystroke_now = fgetc(stdin); //Stores key value pressed
if (keystroke_now == 'q')
i=1;
else{
i=0;
}
//fprintf(stderr,"%d ",i);
}
}//END WHILE
if(keystroke_now == 'q'){
cout << "Program Forced End" << endl;
}
loopTimeTotalEnd = cflieCopter1->currentTime() - initTime1;
loopTimeTotal = loopTimeTotalEnd - loopTimeTotalStart;
} //END VRPN GO
</pre>
</code>
</blockquote>
::'''Note:''' The most important part of this is the <code>tracker->mainloop();</code> functions. These functions are what calls the Callback if there is new data waiting!!
::You can see an example of the code that is executed whenever the [[:Callbacks#Full Callback Example|callback is triggered]]
==Full Callback Example==
Below is a full Callback example for Crazyflie1:
<blockquote>
<code>
<pre>
#if NUM_QUADS >= 1
void VRPN_CALLBACK handle_pos(void*, const vrpn_TRACKERCB t) {
//cout << "First Callback" << endl;
if(vrpnPacketBackup1 < 2) //If VRPN Buffer does NOT have old packets stored up, run main code
{
loopTime1Start = cflieCopter1->currentTime() - initTime1;
loopTime1Delta = loopTime1Start - loopTime1Prev; //Calculates time difference between each loop start
loopTime1Prev = loopTime1Start;
vrpnPacketTime1 = t.msg_time.tv_sec + (t.msg_time.tv_usec / 1000000.0);
vrpnPacketDelta1 = vrpnPacketTime1 - vrpnPacketTime1Prev; //Calculates time between VRPN Data Packets (almost always 0.01 sec)
vrpnPacketTime1Prev = vrpnPacketTime1;
vrpnPacketBackup1 = ceil(loopTime1Delta/vrpnPacketDelta1); //Calculates estimated # of packets built up in VRPN buffer.
controllerSetAllDt(&pidCtrl1, vrpnPacketDelta1); //Variable dt for controller based on time between packets | vrpnPacketDelta1
#if NUM_QUADS == 2
cflieCopter2->cheat_process_packets();
#elif NUM_QUADS == 3
cflieCopter3->cheat_process_packets();
#elif NUM_QUADS == 4
cflieCopter2->cheat_process_packets();
#endif
crRadio1->clearPackets(); //Clears the USB Radio Buffer before switching Radio channels
crRadio1->setChannel( cflieCopter1->radioChannel() );
frameCount++;
// Get the euler angles
q_vec_type euler;
q_to_euler(euler, t.quat);
xPosition1 = t.pos[0];
yPosition1 = t.pos[1]; //Stores X, Y, and Z Position for use in other Callbacks (external)
zPosition1 = -t.pos[2] + 0.05;
#if USE_PRINTOUT
cout << "PID Radio 1" << endl << endl;
#endif
#if 0 //Old way of storing Camera Data (most of it was unnecessary) UNUSED
cfliePitch = cflieCopter1->pitch();
cflieRoll = cflieCopter1->roll();
cflieYaw = cflieCopter1->yaw();
cflieThrust = cflieCopter1->thrust();
/* Legend for Camera Data Packet
* Position
* x t.pos[0]
* y t.pos[1]
* z t.pos[2]
*
* Orientation
* yaw euler[0] Rotation
* pitch euler[1] East-West movement
* roll euler[2] North-South movement
* Euler's range goes from -pi : +pi
*/
QUAD quad;
quad.vrpnNow = 0;
vrpn_data_t *vrpnData;
vrpnData = (vrpn_data_t*) malloc(sizeof(vrpn_data_t));
vrpnData->usec = t.msg_time.tv_sec + (t.msg_time.tv_usec / 1000000.0);
vrpnData->x = t.pos[0];
vrpnData->y = t.pos[1];
vrpnData->z = -t.pos[2] + 0.05; //Higher Altitude = Negative z //Added Offset for floor below camera system origin
vrpnData->yaw = euler[0];
vrpnData->pitch = euler[1];
vrpnData->roll = euler[2];
quad.vrpnPrev = quad.vrpnNow;
if (quad.vrpnNow == 0) {
quad.vrpnPrev = 0;
quad.vrpnTime0 = vrpnData->usec;
quad.vrpnNow = vrpnData->usec;
} else {
quad.vrpnNow = vrpnData->usec - quad.vrpnTime0;
}
#endif //END UNUSED
//==============YAW CORRECTION========================= (IMPORTANT!!!: YAW CONTROLLER INPUT IS INVERTED IN simple.cpp FILE***)
camYawDeg1 = -(euler[0] * 57.2958); //Getting Camera Yaw (Converts From Radians TO Degrees)
quadYaw1 = cflieCopter1->yaw(); //Getting Crazyflie Yaw
if (frameCount == 50) {
if (camYawDeg1 < 0.0)
camYawDeg1Off = camYawDeg1 + 360.0; //Converts from +-180 to full 360 degree form
else
camYawDeg1Off = camYawDeg1;
if(quadYaw1 < 0.0)
quadYaw1Off = quadYaw1 + 360.0;
else
quadYaw1Off = quadYaw1;
yawDifference1 = quadYaw1Off - camYawDeg1Off;
cout << "Yaw1 Offset Taken: " << yawDifference1 << endl;
}
correctedYaw1 = camYawDeg1 + yawDifference1;
if(correctedYaw1 > 180.0)
correctedYaw1 -= 360.0;
else if(correctedYaw1 < -180.0)
correctedYaw1 += 360.0;
//===============END YAW CORRECTION=========================
#if USE_PRINTOUT
cout << "X: " << t.pos[0] << endl;
cout << "Y: " << t.pos[1] << endl;
cout << "Z: " << -t.pos[2] + 0.05 << endl;
// cout << "Quad Yaw: " << cflieCopter1->yaw() << endl;
// cout << "Camera Yaw: " << camYawDeg1 << endl;
// cout << "Yaw Offset: " << yawDifference1 << endl;
// cout << "New Desired Yaw: " << yawDesired1 << endl;
cout << "Frame Count: " << frameCount << endl;
#endif
#if USE_KEYBOARD
if (cflieCopter1->m_enumFlightMode == LANDING_MODE) //Landing Mode
{
//CORRECTS PITCH AND ROLL PID ERRORS TO ACCOUNT FOR QUADS CURRENT YAW DIRECTION
// xError1 = cos(correctedYaw1 / 57.2958)*(xPositionDesired1 - xPosition1) - sin(correctedYaw1 / 57.2958)*(yPositionDesired1 - yPosition1);
// yError1 = sin(correctedYaw1 / 57.2958)*(xPositionDesired1 - xPosition1) + cos(correctedYaw1 / 57.2958)*(yPositionDesired1 - yPosition1);
xError1 = xPositionDesired1 - xPosition1;
yError1 = yPositionDesired1 - yPosition1;
controllerSetXYError(&pidCtrl1, xError1, yError1);
controllerCorrectAttitudePID(&pidCtrl1, t.pos[0], t.pos[1], zPosition1, correctedYaw1,
xPositionDesired1, yPositionDesired1, -0.4, yawDesired1,
&rollControlOutput1, &pitchControlOutput1, &yawControlOutput1,
&thrustControlOutput1);
takeOff1 = 0;
} else if (cflieCopter1->m_enumFlightMode == MIRROR_MODE) { //Acts as Master
xPositionDesired1 = -0.012;
yPositionDesired1 = -0.200;
zPositionDesired1 = 0.75;
if( loopTime1Start - lastTime > 4.0 ) //Creates a 'Step' by changing setpoint every 4 seconds
{
toggle = !toggle;
lastTime = loopTime1Start;
}
if(toggle)
{
xStepPositionError1 = xPositionDesired1 - xPosition1;
yStepPositionError1 = yPositionDesired1 - yPosition1;
controllerSetXYError(&pidCtrl1, xStepPositionError1, yStepPositionError1);
controllerCorrectAttitudePID(&pidCtrl1, t.pos[0], t.pos[1], zPosition1, correctedYaw1,
xPositionDesired1, yPositionDesired1, zPositionDesired1,
yawDesired1, &rollControlOutput1, &pitchControlOutput1,
&yawControlOutput1, &thrustControlOutput1);
}
else //Shifts current x and y setpoint 0.65 meters
{
xStepPositionError1 = (xPositionDesired1 + 0.65) - xPosition1;
yStepPositionError1 = (yPositionDesired1 + 0.65) - yPosition1;
controllerSetXYError(&pidCtrl1, xStepPositionError1, yStepPositionError1);
controllerCorrectAttitudePID(&pidCtrl1, t.pos[0], t.pos[1], zPosition1, correctedYaw1,
xPositionDesired1 + 0.65, yPositionDesired1 + 0.65, zPositionDesired1,
yawDesired1, &rollControlOutput1, &pitchControlOutput1,
&yawControlOutput1, &thrustControlOutput1);
//cout << "Toggled!" << endl;
}
} else if (cflieCopter1->m_enumFlightMode == TAKEOFF_MODE) { //correctedYaw1
//CORRECTS PITCH AND ROLL PID ERRORS TO ACCOUNT FOR QUADS CURRENT YAW DIRECTION
// xError1 = cos(correctedYaw1 / 57.2958)*(xPositionDesired1 - xPosition1) - sin(correctedYaw1 / 57.2958)*(yPositionDesired1 - yPosition1);
// yError1 = sin(correctedYaw1 / 57.2958)*(xPositionDesired1 - xPosition1) + cos(correctedYaw1 / 57.2958)*(yPositionDesired1 - yPosition1);
xError1 = xPositionDesired1 - xPosition1;
yError1 = yPositionDesired1 - yPosition1;
controllerSetXYError(&pidCtrl1, xError1, yError1);
controllerCorrectAttitudePID(&pidCtrl1, t.pos[0], t.pos[1], zPosition1, correctedYaw1,
xPositionDesired1, yPositionDesired1, zPositionDesired1,
yawDesired1, &rollControlOutput1, &pitchControlOutput1,
&yawControlOutput1, &thrustControlOutput1);
}
else if (cflieCopter1->m_enumFlightMode == HAND_MODE) {
//CORRECTS PITCH AND ROLL PID ERRORS TO ACCOUNT FOR QUADS CURRENT YAW DIRECTION
// xError1 = cos(correctedYaw1 / 57.2958)*(xPositionDesired1 - xPosition1) - sin(correctedYaw1 / 57.2958)*(yPositionDesired1 - yPosition1);
// yError1 = sin(correctedYaw1 / 57.2958)*(xPositionDesired1 - xPosition1) + cos(correctedYaw1 / 57.2958)*(yPositionDesired1 - yPosition1);
xError1 = (xPositionHand - 0.5) - xPosition1;
yError1 = (yPositionHand + 0.5) - yPosition1;
controllerSetXYError(&pidCtrl1, xError1, yError1);
controllerCorrectAttitudePID(&pidCtrl1, t.pos[0], t.pos[1], zPosition1, correctedYaw1,
xPositionDesired1, yPositionDesired1, zPositionDesired1,
yawDesired1, &rollControlOutput1, &pitchControlOutput1,
&yawControlOutput1, &thrustControlOutput1);
}
else if(flap){ //Flap Mode (OBSOLETE)
// cflieCopter1->setThrust(20000);
// cflieCopter2->setThrust(20000); //45000 Thrust of Crazyflie2.0 to match Crazyflie1.0
// cflieCopter2->setYaw(90);
// lastTime = cflieCopter2->currentTime();
curTime = cflieCopter2->currentTime();
if( curTime - lastTime > 1.0 )
{
toggle = !toggle;
lastTime = curTime;
}
if( toggle ){
cflieCopter1->setThrust( 20000 );
printf("Low %.3lf ", curTime);
}
else
{
cflieCopter1->setThrust( 40000 );
printf("High %.3lf ", curTime);
}
}
else if(cflieCopter1->m_enumFlightMode == GROUNDED_MODE){
controllerResetAllPID(&pidCtrl1);
rollControlOutput1 = 0;
pitchControlOutput1 = 0;
yawControlOutput1 = 0;
thrustControlOutput1 = 0;
}
else{ //Emergency Case (Should never happen)
controllerResetAllPID(&pidCtrl1);
rollControlOutput1 = 0;
pitchControlOutput1 = 0;
yawControlOutput1 = 0;
thrustControlOutput1 = 0;
}
#else //If keyboard input NOT enabled then just run default Controller
controllerCorrectAttitudePID(&pidCtrl1, t.pos[0], t.pos[1], -t.pos[2], correctedYaw1,
xPositionDesired1, yPositionDesired1, zPositionDesired1,
yawDesired1, &rollControlOutput1, &pitchControlOutput1,
&yawControlOutput1, &thrustControlOutput1);
#endif
RunCrazyflie(crRadio1, cflieCopter1, rollControlOutput1,
pitchControlOutput1, yawControlOutput1, thrustControlOutput1);
#if USE_LOGGING
#if USE_BASIC_LOGGING
fprintf(out1, "%.6f\t\t", cflieCopter1->currentTime() - initTime1 );
fprintf(out1, "%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.6f\t\t%.6f\t\t%.6f\t\t%.6f\t\t%.6f\t\t%.6f\t\t%d\t\t%d",
cflieCopter1->roll(),
cflieCopter1->pitch(),
quadYaw1,
t.pos[0],
t.pos[1],
-t.pos[2],
camYawDeg1,
correctedYaw1,
loopTimeTotal,
loopTimeTotalDelta,
loopTime1,
loopTime1Delta,
vrpnPacketDelta1,
vrpnPacketTime1,
vrpnPacketBackup1,
cflieCopter1->radioRSSI()); //
fprintf(out1, "\n");
#else
//FULL LOGGING ROUTINE (***CAUSES MAJOR BOTTLENECK IN CODE TIMING THE MORE VARIABLES YOU LOG***)
fprintf(out1, "%.6f\t\t", cflieCopter1->currentTime() - initTime1 );
fprintf(out1, "%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.6f\t\t%.6f\t\t%.6f\t\t%.6f\t\t%.6f\t\t%.6f\t\t%d\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%d\t\t%.3f\t\t%.3f\t\t%.3f\t\t%lu\t\t%lu\t\t%lu\t\t%lu\t\t%.3f\t\t%.3f\t\t%.3f",
cflieCopter1->roll(),
cflieCopter1->pitch(),
quadYaw1,
t.pos[0],
t.pos[1],
-t.pos[2],
camYawDeg1,
correctedYaw1,
loopTimeTotal,
loopTimeTotalDelta,
loopTime1,
loopTime1Delta,
vrpnPacketDelta1,
vrpnPacketTime1,
vrpnPacketBackup1,
xPositionDesired1,
yPositionDesired1,
zPositionDesired1,
yawDesired1,
pitchControlOutput1,
rollControlOutput1,
yawControlOutput1,
thrustControlOutput1,
cflieCopter1->radioRSSI(),
euler[0],
euler[1],
euler[2],
cflieCopter1->motor1(),
cflieCopter1->motor2(),
cflieCopter1->motor3(),
cflieCopter1->motor4(),
cflieCopter1->gyroX(),
cflieCopter1->gyroY(),
cflieCopter1->gyroZ()); //
fprintf(out1, "\n");
#endif
#endif
#if 0 //(UNUSED)
if (tcp_client_ON) {
readMulticast(); //(argc < 1 = Listen Mode)
// runTCPClient();
}
#endif
//cout << "PID Radio 2" << endl << endl;
loopTime1End = cflieCopter1->currentTime() - initTime1;
loopTime1 = loopTime1End - loopTime1Start;
}
else if(vrpnPacketBackup1 < 0){ //Failsafe so can't go below 0 (should never happen) | || (vrpnPacketBackup1 > 20)?
vrpnPacketBackup1 = 0;
}
else if(vrpnPacketBackup1 >= 2){
vrpnPacketBackup1 --;
// cout << "VRPN Packet Backup 1 Detected: " << vrpnPacketBackup1 << endl;
}//End Packet Backup If check
} //End Callback 1
</pre>
</code>
</blockquote>
----
<center> '''Main Directory''' </center>
<center> [[Crazyflie Swarm|Crazyflie Swarm Home]] | [[PC Client Software]] | [[USB Radio]] | [[Firmware]] | [[FAQ]] </center>
<center> '''Modifications Directory''' </center>
<center> [[Controller]] | [[Logging]] | [[Keyboard Commands]] | [[USB Radio#Changing Radio Channel|Changing Radio Channel]] | [[Flight Modes]] | [[Callbacks]] | [[Adding a Crazyflie]] | [[Firmware]] </center>
e54328f5645cdae2c8e508ea41a94a2d96249159
153
152
2016-07-28T17:16:43Z
Jnoronha
3
/* Full Callback Example */ added timestamp to callback example
wikitext
text/x-wiki
A callback is a segment of code that will run only when a certain condition is satisfied. For the Swarm Platform, the callbacks we use are triggered by the VRPN communications protocol used by the Camera System. Whenever the Client receives a new packet of data from the Camera System the callback will be triggered.
See [[Camera System and VRPN|VRPN and the Camera System]] if you want more detail on those systems before you start.
==Registering a Callback==
Before we can do anything we need to set up a callback that executes when new data is present.
:1. Use the VRPN Library to create a ''Connection'' and ''Tracker_Remote'' object pointers (code in ''vrpn.cpp''):
<blockquote>
<code>
<pre>
vrpn_Connection *connection;
vrpn_Tracker_Remote *trackerHand;
vrpn_Tracker_Remote *tracker;
vrpn_Tracker_Remote *tracker2;
vrpn_Tracker_Remote *tracker3;
vrpn_Tracker_Remote *tracker4;
</pre>
</code>
</blockquote>
::'''Note:''' We need a ''Tracker_Remote'' object for each constellation we want to track (Hand and each Crazyflie in the Swarm)
:2. Now we create a function to (code in ''vrpn.cpp''):
:#Register the connection to the Server computer
:#Assign each ''Tracker_Remote'' object to a valid constellation name on the Server computer
:#Link that constellation to a callback
:*Flowchart of the Init process
[[Image:VRPN_INIT.png]]
:*Full code
<blockquote>
<code>
<pre>
void vrpn_init(std::string connectionName, void (*callbackHand)(void*, const vrpn_TRACKERCB),
void (*callback)(void*, const vrpn_TRACKERCB), void (*callback2)(void*, const vrpn_TRACKERCB),
void (*callback3)(void*, const vrpn_TRACKERCB), void (*callback4)(void*, const vrpn_TRACKERCB), char *key) {
connection = vrpn_get_connection_by_name(connectionName.c_str());
#if USE_HAND
trackerHand = new vrpn_Tracker_Remote("hand", connection);
#endif
tracker = new vrpn_Tracker_Remote("Crazyflie21", connection);
tracker2 = new vrpn_Tracker_Remote("Crazyflie2", connection);
tracker3 = new vrpn_Tracker_Remote("Crazyflie22", connection);
tracker4 = new vrpn_Tracker_Remote("Crazyflie23", connection);
#if USE_HAND
trackerHand->register_change_handler(0, callbackHand);
#endif
tracker->register_change_handler(0, callback);
tracker2->register_change_handler(0, callback2);
tracker3->register_change_handler(0, callback3);
tracker4->register_change_handler(0, callback4);
usleep(2000);
}
</pre>
</code>
</blockquote>
::'''Note 1:''' We pass in the following as inputs to the function:
::*''string connectionName'' is the "'''IP address:Port'''" of the Computer running the Camera System
::**(You can see the ''VRPN Broadcast Port'' used in the on the middle-right pane called ''Streaming Properties'')
::*A callback pointer for each constellation we want to track (These will be established in the [[:Callbacks#Using a Callback in the Swarm Client|Using a Callback]] section)
::'''Note 2:''' Notice the names of each ''tracker'' '''match the names of the constellations''' in the Camera System Software (shown below):
::[[Image:TrackingToolsCrazyflieConstellationParams.png|800px]]
==Using a Callback in the Swarm Client==
The Swarm Client needs to re-establish the connection to the VRPN server for each test.
===Initializing the Callbacks===
:1. Create the Callback Objects (code in ''eris_vrpn.cpp''):
<blockquote>
<code>
<pre>
void VRPN_CALLBACK handle_hand(void*, const vrpn_TRACKERCB t);
void VRPN_CALLBACK handle_pos(void*, const vrpn_TRACKERCB t); //Old name scheme (represents Callback for Crazyflie1)
void VRPN_CALLBACK handle_Crazyflie2(void*, const vrpn_TRACKERCB t);
void VRPN_CALLBACK handle_Crazyflie3(void*, const vrpn_TRACKERCB t);
void VRPN_CALLBACK handle_Crazyflie4(void*, const vrpn_TRACKERCB t);
</pre>
</code>
</blockquote>
:2. [[:Callbacks#Registering a Callback|Register the connection]] and constellations to the Callbacks (code in ''eris_vrpn.cpp''):
<blockquote>
<code>
<pre>
#if NUM_QUADS == 1
vrpn_init("192.168.0.120:3883", handle_hand, handle_pos, NULL, NULL, NULL, NULL);
#elif NUM_QUADS == 2
vrpn_init("192.168.0.120:3883", handle_hand, handle_pos, handle_Crazyflie2, NULL, NULL, NULL);
#elif NUM_QUADS == 3
vrpn_init("192.168.0.120:3883", handle_hand, handle_pos, handle_Crazyflie2, handle_Crazyflie3, NULL, NULL);
#elif NUM_QUADS == 4
vrpn_init("192.168.0.120:3883", handle_hand, handle_pos, handle_Crazyflie2, handle_Crazyflie3, handle_Crazyflie4, NULL);
#endif
</pre>
</code>
</blockquote>
::'''Note:''' If we don't want to track a certain Crazyflie (i.e. we only want to fly 2 Crazyflies) we can just pass <code>NULL</code> into the init function for the callbacks we don't care about.
===Calling a Callback===
:3. Start the mainloop: <code>vrpn_go()</code> (code in ''vrpn.cpp'') (function called in ''eris_vrpn.cpp'')
::*A flowchart of the vrpn_go() function:
[[Image:VRPNGO.png|500px]]
::*Full vrpn_go() code (code in ''vrpn.cpp''):
<blockquote>
<code>
<pre>
void vrpn_go() {
int i = 0; //for ending the while loop
while(!i){
readKeyboard(); //Triggers actions based on key value read
nearGround();
#if USE_HAND
updateHand(); //Checks for Valid Hand Gestures
#endif
//Calculates Total Loop Timing
loopTimeTotalStart = cflieCopter1->currentTime() - initTime1;
loopTimeTotalDelta = loopTimeTotalStart - loopTimeTotalPrev;
loopTimeTotalPrev = loopTimeTotalStart;
connection->mainloop(); //Pings the Server Connection to see if still alive
#if USE_HAND
trackerHand->mainloop(); //Checks if Hand constellation has new data (runs callback if true)
#endif
tracker->mainloop(); //IMPORTANT: Checks if Crazyflie1 constellation has new data (runs callback if true)
tracker2->mainloop(); //Same...
tracker3->mainloop();
tracker4->mainloop();
usleep(200); //Was 200
nonblock(1);
usleep(1);
i = kbhit(); //keyboard hit (state change)
if (i!=0)
{
keystroke_now = fgetc(stdin); //Stores key value pressed
if (keystroke_now == 'q')
i=1;
else{
i=0;
}
//fprintf(stderr,"%d ",i);
}
}//END WHILE
if(keystroke_now == 'q'){
cout << "Program Forced End" << endl;
}
loopTimeTotalEnd = cflieCopter1->currentTime() - initTime1;
loopTimeTotal = loopTimeTotalEnd - loopTimeTotalStart;
} //END VRPN GO
</pre>
</code>
</blockquote>
::'''Note:''' The most important part of this is the <code>tracker->mainloop();</code> functions. These functions are what calls the Callback if there is new data waiting!!
::You can see an example of the code that is executed whenever the [[:Callbacks#Full Callback Example|callback is triggered]]
==Full Callback Example==
Below is a full Callback example for Crazyflie1 (as of 7/27/16):
<blockquote>
<code>
<pre>
#if NUM_QUADS >= 1
void VRPN_CALLBACK handle_pos(void*, const vrpn_TRACKERCB t) {
//cout << "First Callback" << endl;
if(vrpnPacketBackup1 < 2) //If VRPN Buffer does NOT have old packets stored up, run main code
{
loopTime1Start = cflieCopter1->currentTime() - initTime1;
loopTime1Delta = loopTime1Start - loopTime1Prev; //Calculates time difference between each loop start
loopTime1Prev = loopTime1Start;
vrpnPacketTime1 = t.msg_time.tv_sec + (t.msg_time.tv_usec / 1000000.0);
vrpnPacketDelta1 = vrpnPacketTime1 - vrpnPacketTime1Prev; //Calculates time between VRPN Data Packets (almost always 0.01 sec)
vrpnPacketTime1Prev = vrpnPacketTime1;
vrpnPacketBackup1 = ceil(loopTime1Delta/vrpnPacketDelta1); //Calculates estimated # of packets built up in VRPN buffer.
controllerSetAllDt(&pidCtrl1, vrpnPacketDelta1); //Variable dt for controller based on time between packets | vrpnPacketDelta1
#if NUM_QUADS == 2
cflieCopter2->cheat_process_packets();
#elif NUM_QUADS == 3
cflieCopter3->cheat_process_packets();
#elif NUM_QUADS == 4
cflieCopter2->cheat_process_packets();
#endif
crRadio1->clearPackets(); //Clears the USB Radio Buffer before switching Radio channels
crRadio1->setChannel( cflieCopter1->radioChannel() );
frameCount++;
// Get the euler angles
q_vec_type euler;
q_to_euler(euler, t.quat);
xPosition1 = t.pos[0];
yPosition1 = t.pos[1]; //Stores X, Y, and Z Position for use in other Callbacks (external)
zPosition1 = -t.pos[2] + 0.05;
#if USE_PRINTOUT
cout << "PID Radio 1" << endl << endl;
#endif
#if 0 //Old way of storing Camera Data (most of it was unnecessary) UNUSED
cfliePitch = cflieCopter1->pitch();
cflieRoll = cflieCopter1->roll();
cflieYaw = cflieCopter1->yaw();
cflieThrust = cflieCopter1->thrust();
/* Legend for Camera Data Packet
* Position
* x t.pos[0]
* y t.pos[1]
* z t.pos[2]
*
* Orientation
* yaw euler[0] Rotation
* pitch euler[1] East-West movement
* roll euler[2] North-South movement
* Euler's range goes from -pi : +pi
*/
QUAD quad;
quad.vrpnNow = 0;
vrpn_data_t *vrpnData;
vrpnData = (vrpn_data_t*) malloc(sizeof(vrpn_data_t));
vrpnData->usec = t.msg_time.tv_sec + (t.msg_time.tv_usec / 1000000.0);
vrpnData->x = t.pos[0];
vrpnData->y = t.pos[1];
vrpnData->z = -t.pos[2] + 0.05; //Higher Altitude = Negative z //Added Offset for floor below camera system origin
vrpnData->yaw = euler[0];
vrpnData->pitch = euler[1];
vrpnData->roll = euler[2];
quad.vrpnPrev = quad.vrpnNow;
if (quad.vrpnNow == 0) {
quad.vrpnPrev = 0;
quad.vrpnTime0 = vrpnData->usec;
quad.vrpnNow = vrpnData->usec;
} else {
quad.vrpnNow = vrpnData->usec - quad.vrpnTime0;
}
#endif //END UNUSED
//==============YAW CORRECTION========================= (IMPORTANT!!!: YAW CONTROLLER INPUT IS INVERTED IN simple.cpp FILE***)
camYawDeg1 = -(euler[0] * 57.2958); //Getting Camera Yaw (Converts From Radians TO Degrees)
quadYaw1 = cflieCopter1->yaw(); //Getting Crazyflie Yaw
if (frameCount == 50) {
if (camYawDeg1 < 0.0)
camYawDeg1Off = camYawDeg1 + 360.0; //Converts from +-180 to full 360 degree form
else
camYawDeg1Off = camYawDeg1;
if(quadYaw1 < 0.0)
quadYaw1Off = quadYaw1 + 360.0;
else
quadYaw1Off = quadYaw1;
yawDifference1 = quadYaw1Off - camYawDeg1Off;
cout << "Yaw1 Offset Taken: " << yawDifference1 << endl;
}
correctedYaw1 = camYawDeg1 + yawDifference1;
if(correctedYaw1 > 180.0)
correctedYaw1 -= 360.0;
else if(correctedYaw1 < -180.0)
correctedYaw1 += 360.0;
//===============END YAW CORRECTION=========================
#if USE_PRINTOUT
cout << "X: " << t.pos[0] << endl;
cout << "Y: " << t.pos[1] << endl;
cout << "Z: " << -t.pos[2] + 0.05 << endl;
// cout << "Quad Yaw: " << cflieCopter1->yaw() << endl;
// cout << "Camera Yaw: " << camYawDeg1 << endl;
// cout << "Yaw Offset: " << yawDifference1 << endl;
// cout << "New Desired Yaw: " << yawDesired1 << endl;
cout << "Frame Count: " << frameCount << endl;
#endif
#if USE_KEYBOARD
if (cflieCopter1->m_enumFlightMode == LANDING_MODE) //Landing Mode
{
//CORRECTS PITCH AND ROLL PID ERRORS TO ACCOUNT FOR QUADS CURRENT YAW DIRECTION
// xError1 = cos(correctedYaw1 / 57.2958)*(xPositionDesired1 - xPosition1) - sin(correctedYaw1 / 57.2958)*(yPositionDesired1 - yPosition1);
// yError1 = sin(correctedYaw1 / 57.2958)*(xPositionDesired1 - xPosition1) + cos(correctedYaw1 / 57.2958)*(yPositionDesired1 - yPosition1);
xError1 = xPositionDesired1 - xPosition1;
yError1 = yPositionDesired1 - yPosition1;
controllerSetXYError(&pidCtrl1, xError1, yError1);
controllerCorrectAttitudePID(&pidCtrl1, t.pos[0], t.pos[1], zPosition1, correctedYaw1,
xPositionDesired1, yPositionDesired1, -0.4, yawDesired1,
&rollControlOutput1, &pitchControlOutput1, &yawControlOutput1,
&thrustControlOutput1);
takeOff1 = 0;
} else if (cflieCopter1->m_enumFlightMode == MIRROR_MODE) { //Acts as Master
xPositionDesired1 = -0.012;
yPositionDesired1 = -0.200;
zPositionDesired1 = 0.75;
if( loopTime1Start - lastTime > 4.0 ) //Creates a 'Step' by changing setpoint every 4 seconds
{
toggle = !toggle;
lastTime = loopTime1Start;
}
if(toggle)
{
xStepPositionError1 = xPositionDesired1 - xPosition1;
yStepPositionError1 = yPositionDesired1 - yPosition1;
controllerSetXYError(&pidCtrl1, xStepPositionError1, yStepPositionError1);
controllerCorrectAttitudePID(&pidCtrl1, t.pos[0], t.pos[1], zPosition1, correctedYaw1,
xPositionDesired1, yPositionDesired1, zPositionDesired1,
yawDesired1, &rollControlOutput1, &pitchControlOutput1,
&yawControlOutput1, &thrustControlOutput1);
}
else //Shifts current x and y setpoint 0.65 meters
{
xStepPositionError1 = (xPositionDesired1 + 0.65) - xPosition1;
yStepPositionError1 = (yPositionDesired1 + 0.65) - yPosition1;
controllerSetXYError(&pidCtrl1, xStepPositionError1, yStepPositionError1);
controllerCorrectAttitudePID(&pidCtrl1, t.pos[0], t.pos[1], zPosition1, correctedYaw1,
xPositionDesired1 + 0.65, yPositionDesired1 + 0.65, zPositionDesired1,
yawDesired1, &rollControlOutput1, &pitchControlOutput1,
&yawControlOutput1, &thrustControlOutput1);
//cout << "Toggled!" << endl;
}
} else if (cflieCopter1->m_enumFlightMode == TAKEOFF_MODE) { //correctedYaw1
//CORRECTS PITCH AND ROLL PID ERRORS TO ACCOUNT FOR QUADS CURRENT YAW DIRECTION
// xError1 = cos(correctedYaw1 / 57.2958)*(xPositionDesired1 - xPosition1) - sin(correctedYaw1 / 57.2958)*(yPositionDesired1 - yPosition1);
// yError1 = sin(correctedYaw1 / 57.2958)*(xPositionDesired1 - xPosition1) + cos(correctedYaw1 / 57.2958)*(yPositionDesired1 - yPosition1);
xError1 = xPositionDesired1 - xPosition1;
yError1 = yPositionDesired1 - yPosition1;
controllerSetXYError(&pidCtrl1, xError1, yError1);
controllerCorrectAttitudePID(&pidCtrl1, t.pos[0], t.pos[1], zPosition1, correctedYaw1,
xPositionDesired1, yPositionDesired1, zPositionDesired1,
yawDesired1, &rollControlOutput1, &pitchControlOutput1,
&yawControlOutput1, &thrustControlOutput1);
}
else if (cflieCopter1->m_enumFlightMode == HAND_MODE) {
//CORRECTS PITCH AND ROLL PID ERRORS TO ACCOUNT FOR QUADS CURRENT YAW DIRECTION
// xError1 = cos(correctedYaw1 / 57.2958)*(xPositionDesired1 - xPosition1) - sin(correctedYaw1 / 57.2958)*(yPositionDesired1 - yPosition1);
// yError1 = sin(correctedYaw1 / 57.2958)*(xPositionDesired1 - xPosition1) + cos(correctedYaw1 / 57.2958)*(yPositionDesired1 - yPosition1);
xError1 = (xPositionHand - 0.5) - xPosition1;
yError1 = (yPositionHand + 0.5) - yPosition1;
controllerSetXYError(&pidCtrl1, xError1, yError1);
controllerCorrectAttitudePID(&pidCtrl1, t.pos[0], t.pos[1], zPosition1, correctedYaw1,
xPositionDesired1, yPositionDesired1, zPositionDesired1,
yawDesired1, &rollControlOutput1, &pitchControlOutput1,
&yawControlOutput1, &thrustControlOutput1);
}
else if(flap){ //Flap Mode (OBSOLETE)
// cflieCopter1->setThrust(20000);
// cflieCopter2->setThrust(20000); //45000 Thrust of Crazyflie2.0 to match Crazyflie1.0
// cflieCopter2->setYaw(90);
// lastTime = cflieCopter2->currentTime();
curTime = cflieCopter2->currentTime();
if( curTime - lastTime > 1.0 )
{
toggle = !toggle;
lastTime = curTime;
}
if( toggle ){
cflieCopter1->setThrust( 20000 );
printf("Low %.3lf ", curTime);
}
else
{
cflieCopter1->setThrust( 40000 );
printf("High %.3lf ", curTime);
}
}
else if(cflieCopter1->m_enumFlightMode == GROUNDED_MODE){
controllerResetAllPID(&pidCtrl1);
rollControlOutput1 = 0;
pitchControlOutput1 = 0;
yawControlOutput1 = 0;
thrustControlOutput1 = 0;
}
else{ //Emergency Case (Should never happen)
controllerResetAllPID(&pidCtrl1);
rollControlOutput1 = 0;
pitchControlOutput1 = 0;
yawControlOutput1 = 0;
thrustControlOutput1 = 0;
}
#else //If keyboard input NOT enabled then just run default Controller
controllerCorrectAttitudePID(&pidCtrl1, t.pos[0], t.pos[1], -t.pos[2], correctedYaw1,
xPositionDesired1, yPositionDesired1, zPositionDesired1,
yawDesired1, &rollControlOutput1, &pitchControlOutput1,
&yawControlOutput1, &thrustControlOutput1);
#endif
RunCrazyflie(crRadio1, cflieCopter1, rollControlOutput1,
pitchControlOutput1, yawControlOutput1, thrustControlOutput1);
#if USE_LOGGING
#if USE_BASIC_LOGGING
fprintf(out1, "%.6f\t\t", cflieCopter1->currentTime() - initTime1 );
fprintf(out1, "%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.6f\t\t%.6f\t\t%.6f\t\t%.6f\t\t%.6f\t\t%.6f\t\t%d\t\t%d",
cflieCopter1->roll(),
cflieCopter1->pitch(),
quadYaw1,
t.pos[0],
t.pos[1],
-t.pos[2],
camYawDeg1,
correctedYaw1,
loopTimeTotal,
loopTimeTotalDelta,
loopTime1,
loopTime1Delta,
vrpnPacketDelta1,
vrpnPacketTime1,
vrpnPacketBackup1,
cflieCopter1->radioRSSI()); //
fprintf(out1, "\n");
#else
//FULL LOGGING ROUTINE (***CAUSES MAJOR BOTTLENECK IN CODE TIMING THE MORE VARIABLES YOU LOG***)
fprintf(out1, "%.6f\t\t", cflieCopter1->currentTime() - initTime1 );
fprintf(out1, "%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.6f\t\t%.6f\t\t%.6f\t\t%.6f\t\t%.6f\t\t%.6f\t\t%d\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%d\t\t%.3f\t\t%.3f\t\t%.3f\t\t%lu\t\t%lu\t\t%lu\t\t%lu\t\t%.3f\t\t%.3f\t\t%.3f",
cflieCopter1->roll(),
cflieCopter1->pitch(),
quadYaw1,
t.pos[0],
t.pos[1],
-t.pos[2],
camYawDeg1,
correctedYaw1,
loopTimeTotal,
loopTimeTotalDelta,
loopTime1,
loopTime1Delta,
vrpnPacketDelta1,
vrpnPacketTime1,
vrpnPacketBackup1,
xPositionDesired1,
yPositionDesired1,
zPositionDesired1,
yawDesired1,
pitchControlOutput1,
rollControlOutput1,
yawControlOutput1,
thrustControlOutput1,
cflieCopter1->radioRSSI(),
euler[0],
euler[1],
euler[2],
cflieCopter1->motor1(),
cflieCopter1->motor2(),
cflieCopter1->motor3(),
cflieCopter1->motor4(),
cflieCopter1->gyroX(),
cflieCopter1->gyroY(),
cflieCopter1->gyroZ()); //
fprintf(out1, "\n");
#endif
#endif
#if 0 //(UNUSED)
if (tcp_client_ON) {
readMulticast(); //(argc < 1 = Listen Mode)
// runTCPClient();
}
#endif
//cout << "PID Radio 2" << endl << endl;
loopTime1End = cflieCopter1->currentTime() - initTime1;
loopTime1 = loopTime1End - loopTime1Start;
}
else if(vrpnPacketBackup1 < 0){ //Failsafe so can't go below 0 (should never happen) | || (vrpnPacketBackup1 > 20)?
vrpnPacketBackup1 = 0;
}
else if(vrpnPacketBackup1 >= 2){
vrpnPacketBackup1 --;
// cout << "VRPN Packet Backup 1 Detected: " << vrpnPacketBackup1 << endl;
}//End Packet Backup If check
} //End Callback 1
</pre>
</code>
</blockquote>
----
<center> '''Main Directory''' </center>
<center> [[Crazyflie Swarm|Crazyflie Swarm Home]] | [[PC Client Software]] | [[USB Radio]] | [[Firmware]] | [[FAQ]] </center>
<center> '''Modifications Directory''' </center>
<center> [[Controller]] | [[Logging]] | [[Keyboard Commands]] | [[USB Radio#Changing Radio Channel|Changing Radio Channel]] | [[Flight Modes]] | [[Callbacks]] | [[Adding a Crazyflie]] | [[Firmware]] </center>
e7cbea4809638111c1eaebb31e51f8c7c20c5717
Adding a Crazyflie
0
46
154
2016-07-28T17:45:13Z
Jnoronha
3
added changes to vrpn cpp and h and eris_vrpn.cpp
wikitext
text/x-wiki
Adding a Crazyflie to the Swarm is simple, but tedious. It's basically just replicating a copy of the other Crazyflies code, but there are multiple files you will need to make changes in. The following list should help you locate all the code you need to replicate:
==Changes in ''vrpn.cpp''==
<blockquote>
<code>
<pre>
vrpn_Tracker_Remote *tracker#;
extern float xPositionDesired#;
extern float yPositionDesired#;
extern float zPositionDesired#;
extern float yawDesired#;
extern float xPosition#;
extern float yPosition#;
extern float zPosition#;
extern CCrazyflie *cflieCopter#;
extern double initTime#;
extern char takeOff#;
extern double takeOffTime#;
void vrpn_init(std::string connectionName, void (*callback)(void*, const vrpn_TRACKERCB),
void (*callback2)(void*, const vrpn_TRACKERCB), void (*callback#)(void*, const vrpn_TRACKERCB), ......, char *key) {
tracker# = new vrpn_Tracker_Remote("Crazyflie2#", connection);
tracker#->register_change_handler(0, callback#);
tracker#->mainloop();
</pre>
</code>
</blockquote>
===Changes in ''nearGround()''===
<blockquote>
<code>
<pre>
void nearGround() //During Landing Mode checks how close to ground quad is for shutdown
{
...
...
...
if(cflieCopter#){
if((cflieCopter#->m_enumFlightMode == LANDING_MODE) && (zPosition# < 0.05))
{
cflieCopter#->m_enumFlightMode = GROUNDED_MODE;
}
}
}
</pre>
</code>
</blockquote>
===Changes in ''updateHand()''===
<blockquote>
<code>
<pre>
void updateHand()
{
if(handMode == 1)
{
// cout << "Hand Roll: " << rollHand << endl;
if(killCount > 5){
...
...
cflieCopter#->m_enumFlightMode = GROUNDED_MODE;
}
else if(trackCount > 5){
...
...
cflieCopter#->m_enumFlightMode = HAND_MODE;
}
else{
...
...
if(zPositionHand > 1.6)
{
...
...
cflieCopter#->m_enumFlightMode = TAKEOFF_MODE;
cout << "Hand Mode: Launching Quads" << endl;
}
else if(zPositionHand < 0.4)
{
...
...
cflieCopter#->m_enumFlightMode = LANDING_MODE;
...
}
}
}
}
</pre>
</code>
</blockquote>
==Changes in ''vrpn.h''==
<blockquote>
<code>
<pre>
void vrpn_init(std::string connectionName, void (*callback)(void*, const vrpn_TRACKERCB),
void (*callback2)(void*, const vrpn_TRACKERCB), void (*callback#)(void*, const vrpn_TRACKERCB), ...., char *key);
</pre>
</code>
</blockquote>
==Changes in ''eris_vrpn.cpp''==
===Global Variables===
<blockquote>
<code>
<pre>
void VRPN_CALLBACK handle_Crazyflie#(void*, const vrpn_TRACKERCB t);
CCrazyRadio *crRadio# = 0; //***NOT NECESSARY IF LESS THAN 3 QUADS PER RADIO***
CCrazyflie *cflieCopter# = 0;
ControllerObject pidCtrl# = { 0 }; // init all fields to zero
float rollControlOutput#;
float pitchControlOutput#;
float yawControlOutput#;
float thrustControlOutput#;
double initTime# = 0;
int vrpnPacketBackup# = 0;
double vrpnBackupTime# = 0;
double vrpnBackupTime#Prev = 0;
double vrpnBackupTime#Delta = 0;
float xPositionDesired# = 0.681;
float yPositionDesired# = 0.129;
float zPositionDesired# = 0.6;
float yawDesired# = -90.0;
float yawDifference# = 0;
float quadYaw# = 0;
float prevQuadYaw# = 0;
float camYawDeg# = 0;
float camYawDeg#Off = 0;
float quadYaw#Off = 0;
float correctedYaw# = 0;
float xError# = 0.0;
float yError# = 0.0;
float xStepPositionError# = 0.0;
float yStepPositionError# = 0.0;
float xPosition# = -0.012;
float yPosition# = -0.008; //Default Crazyflie location setpoints
float zPosition# = 0.75;
char takeOff# = 0;
double loopTime#Start = 0;
double loopTime#End = 0;
double loopTime# = 0;
double loopTime#Prev = 0;
double loopTime#Delta = 0;
double vrpnPacketTime# = 0;
double vrpnPacketTime#Prev = 0;
double vrpnPacketDelta# = 0;
FILE * out# = NULL;
</pre>
</code>
</blockquote>
===Changes in ''main()''===
<blockquote>
<code>
<pre>
controllerResetAllPID( &pidCtrl# );
controllerInit( &pidCtrl# );
vrpn_init("192.168.0.120:3883", handle_pos, handle_Crazyflie2, handle_Crazyflie#, handle_Crazyflie(#+1), ..., &keystroke_now);
cflieCopter# = new CCrazyflie(crRadio(radio dongle number), (Radio Channel));
const char * logHeader# = "#Crazyflie# Log File\n\
#Time\t\t........
if(cflieCopter#)
{
out# = fopen("cflie#.txt", "w");
if(out# == NULL)
{
printf("Could not open cflie#.log:errno %d\n", errno);
exit(-1);
}
fprintf(out#, "%s\n", logHeader#);
}
crRadio#->setARDTime(2000); //Sets Wait Time between Packet Retries (**MUST BE IN INCREMENTS OF 250**)
crRadio#->setARC(0); //Sets Number of times Retries Packet Send
crRadio#->setPower(P_0DBM);
cflieCopter#->setSendSetpoints( true );
initTime# = cflieCopter#->currentTime();
cflieCopter#->m_enumFlightMode = GROUNDED_MODE;
fclose(out#);
delete cflieCopter#;
delete crRadio#;
</pre>
</code>
</blockquote>
==Creating a New Callback==
----
<center> '''Main Directory''' </center>
<center> [[Crazyflie Swarm|Crazyflie Swarm Home]] | [[PC Client Software]] | [[USB Radio]] | [[Firmware]] | [[FAQ]] </center>
<center> '''Modifications Directory''' </center>
<center> [[Controller]] | [[Logging]] | [[Keyboard Commands]] | [[USB Radio#Changing Radio Channel|Changing Radio Channel]] | [[Flight Modes]] | [[Callbacks]] | [[Adding a Crazyflie]] | [[Firmware]] </center>
717d18a6f7f0bd76e80ae2aaff790374ccf0ce6b
155
154
2016-07-28T17:51:50Z
Jnoronha
3
/* Creating a New Callback */ added code and list of steps
wikitext
text/x-wiki
Adding a Crazyflie to the Swarm is simple, but tedious. It's basically just replicating a copy of the other Crazyflies code, but there are multiple files you will need to make changes in. The following list should help you locate all the code you need to replicate:
==Changes in ''vrpn.cpp''==
<blockquote>
<code>
<pre>
vrpn_Tracker_Remote *tracker#;
extern float xPositionDesired#;
extern float yPositionDesired#;
extern float zPositionDesired#;
extern float yawDesired#;
extern float xPosition#;
extern float yPosition#;
extern float zPosition#;
extern CCrazyflie *cflieCopter#;
extern double initTime#;
extern char takeOff#;
extern double takeOffTime#;
void vrpn_init(std::string connectionName, void (*callback)(void*, const vrpn_TRACKERCB),
void (*callback2)(void*, const vrpn_TRACKERCB), void (*callback#)(void*, const vrpn_TRACKERCB), ......, char *key) {
tracker# = new vrpn_Tracker_Remote("Crazyflie2#", connection);
tracker#->register_change_handler(0, callback#);
tracker#->mainloop();
</pre>
</code>
</blockquote>
===Changes in ''nearGround()''===
<blockquote>
<code>
<pre>
void nearGround() //During Landing Mode checks how close to ground quad is for shutdown
{
...
...
...
if(cflieCopter#){
if((cflieCopter#->m_enumFlightMode == LANDING_MODE) && (zPosition# < 0.05))
{
cflieCopter#->m_enumFlightMode = GROUNDED_MODE;
}
}
}
</pre>
</code>
</blockquote>
===Changes in ''updateHand()''===
<blockquote>
<code>
<pre>
void updateHand()
{
if(handMode == 1)
{
// cout << "Hand Roll: " << rollHand << endl;
if(killCount > 5){
...
...
cflieCopter#->m_enumFlightMode = GROUNDED_MODE;
}
else if(trackCount > 5){
...
...
cflieCopter#->m_enumFlightMode = HAND_MODE;
}
else{
...
...
if(zPositionHand > 1.6)
{
...
...
cflieCopter#->m_enumFlightMode = TAKEOFF_MODE;
cout << "Hand Mode: Launching Quads" << endl;
}
else if(zPositionHand < 0.4)
{
...
...
cflieCopter#->m_enumFlightMode = LANDING_MODE;
...
}
}
}
}
</pre>
</code>
</blockquote>
==Changes in ''vrpn.h''==
<blockquote>
<code>
<pre>
void vrpn_init(std::string connectionName, void (*callback)(void*, const vrpn_TRACKERCB),
void (*callback2)(void*, const vrpn_TRACKERCB), void (*callback#)(void*, const vrpn_TRACKERCB), ...., char *key);
</pre>
</code>
</blockquote>
==Changes in ''eris_vrpn.cpp''==
===Global Variables===
<blockquote>
<code>
<pre>
void VRPN_CALLBACK handle_Crazyflie#(void*, const vrpn_TRACKERCB t);
CCrazyRadio *crRadio# = 0; //***NOT NECESSARY IF LESS THAN 3 QUADS PER RADIO***
CCrazyflie *cflieCopter# = 0;
ControllerObject pidCtrl# = { 0 }; // init all fields to zero
float rollControlOutput#;
float pitchControlOutput#;
float yawControlOutput#;
float thrustControlOutput#;
double initTime# = 0;
int vrpnPacketBackup# = 0;
double vrpnBackupTime# = 0;
double vrpnBackupTime#Prev = 0;
double vrpnBackupTime#Delta = 0;
float xPositionDesired# = 0.681;
float yPositionDesired# = 0.129;
float zPositionDesired# = 0.6;
float yawDesired# = -90.0;
float yawDifference# = 0;
float quadYaw# = 0;
float prevQuadYaw# = 0;
float camYawDeg# = 0;
float camYawDeg#Off = 0;
float quadYaw#Off = 0;
float correctedYaw# = 0;
float xError# = 0.0;
float yError# = 0.0;
float xStepPositionError# = 0.0;
float yStepPositionError# = 0.0;
float xPosition# = -0.012;
float yPosition# = -0.008; //Default Crazyflie location setpoints
float zPosition# = 0.75;
char takeOff# = 0;
double loopTime#Start = 0;
double loopTime#End = 0;
double loopTime# = 0;
double loopTime#Prev = 0;
double loopTime#Delta = 0;
double vrpnPacketTime# = 0;
double vrpnPacketTime#Prev = 0;
double vrpnPacketDelta# = 0;
FILE * out# = NULL;
</pre>
</code>
</blockquote>
===Changes in ''main()''===
<blockquote>
<code>
<pre>
controllerResetAllPID( &pidCtrl# );
controllerInit( &pidCtrl# );
vrpn_init("192.168.0.120:3883", handle_pos, handle_Crazyflie2, handle_Crazyflie#, handle_Crazyflie(#+1), ..., &keystroke_now);
cflieCopter# = new CCrazyflie(crRadio(radio dongle number), (Radio Channel));
const char * logHeader# = "#Crazyflie# Log File\n\
#Time\t\t........
if(cflieCopter#)
{
out# = fopen("cflie#.txt", "w");
if(out# == NULL)
{
printf("Could not open cflie#.log:errno %d\n", errno);
exit(-1);
}
fprintf(out#, "%s\n", logHeader#);
}
crRadio#->setARDTime(2000); //Sets Wait Time between Packet Retries (**MUST BE IN INCREMENTS OF 250**)
crRadio#->setARC(0); //Sets Number of times Retries Packet Send
crRadio#->setPower(P_0DBM);
cflieCopter#->setSendSetpoints( true );
initTime# = cflieCopter#->currentTime();
cflieCopter#->m_enumFlightMode = GROUNDED_MODE;
fclose(out#);
delete cflieCopter#;
delete crRadio#;
</pre>
</code>
</blockquote>
==Creating a New Callback==
'''Note:''' To make it easier for this section you can:
*COPY and PASTE the callback code directly after the last callback in the Swarm Client
*Use FIND and REPLACE to replace all '#' signs with the Crazyflie number desired
**'''IMPORTANT:''' Be careful, some of the '#' symbols are for the Radio Dongle number also.
<blockquote>
<code>
<pre>
void VRPN_CALLBACK handle_Crazyflie#(void*, const vrpn_TRACKERCB t) {
if(vrpnPacketBackup# < 2) //If VRPN Buffer does NOT have old packets stored up, run main code
{
loopTime#Start = cflieCopter#->currentTime() - initTime#;
loopTime#Delta = loopTime#Start - loopTime#Prev; //Calculates time difference between each loop start
loopTime#Prev = loopTime#Start;
vrpnPacketTime# = t.msg_time.tv_sec + (t.msg_time.tv_usec / 1000000.0);
vrpnPacketDelta# = vrpnPacketTime# - vrpnPacketTime#Prev;
vrpnPacketTime#Prev = vrpnPacketTime#;
vrpnPacketBackup# = ceil(loopTime#Delta/vrpnPacketDelta#); //Calculates estimated # of packets built up in VRPN buffer.
controllerSetAllDt(&pidCtrl#, vrpnPacketDelta#); //Variable dt for controller based on time between packets | vrpnPacketDelta2
cflieCopter1->cheat_process_packets(); //Flush out other Copter Packets
crRadio(#RADIO NUM)->clearPackets();
crRadio(#RADIO NUM)->setChannel( cflieCopter#->radioChannel() );
frameCount++;
// Get the euler angles
q_vec_type euler;
q_to_euler(euler, t.quat);
xPosition# = t.pos[0];
yPosition# = t.pos[1]; //Stores X, Y, and Z Position for use in other Callbacks (external)
zPosition# = -t.pos[2] + 0.05;
#if USE_PRINTOUT
cout << "PID Radio #" << endl << endl;
#endif
#if 0 //UNUSED (old way of storing camera data)
//cout << "\033[2J\033[1;1H"; //Clears Terminal Window to display clean output
cfliePitch = cflieCopter#->pitch();
cflieRoll = cflieCopter#->roll();
cflieYaw = cflieCopter#->yaw();
cflieThrust = cflieCopter#->thrust();
/*
* Position
* x t.pos[0]
* y t.pos[1]
* z t.pos[2]
*
* Orientation
* yaw euler[0] Rotation
* pitch euler[1] East-West movement
* roll euler[2] North-South movement
* Euler's range goes from -pi : +pi
*/
QUAD quad;
quad.vrpnNow = 0;
vrpn_data_t *vrpnData;
vrpnData = (vrpn_data_t*) malloc(sizeof(vrpn_data_t));
vrpnData->usec = t.msg_time.tv_sec + (t.msg_time.tv_usec / 1000000.0);
vrpnData->x = t.pos[0];
vrpnData->y = t.pos[1];
vrpnData->z = -t.pos[2] + 0.05; //Higher Altitude = Negative z //Added Offset for floor below camera system origin
vrpnData->yaw = euler[0];
vrpnData->pitch = euler[1];
vrpnData->roll = euler[2];
xPosition# = t.pos[0];
yPosition# = t.pos[1];
zPosition# = -t.pos[2] + 0.05;
cout << "xPosition of Crazyflie#: " << xPosition# << endl;
quad.vrpnPrev = quad.vrpnNow;
if (quad.vrpnNow == 0) {
quad.vrpnPrev = 0;
quad.vrpnTime0 = vrpnData->usec;
quad.vrpnNow = vrpnData->usec;
} else {
quad.vrpnNow = vrpnData->usec - quad.vrpnTime0;
}
#endif //END UNUSED
//==============YAW CORRECTION========================= (IMPORTANT!!!: YAW CONTROLLER INPUT IS INVERTED IN simple.cpp FILE***)
camYawDeg# = -(euler[0] * 57.2958); //Converts From Radians TO Degrees
quadYaw# = cflieCopter#->yaw();
if (frameCount == 50) {
if (camYawDeg# < 0.0)
camYawDeg#Off = camYawDeg# + 360.0; //Converts from +-180 to full 360 degree form
else
camYawDeg#Off = camYawDeg#;
if(quadYaw# < 0.0)
quadYaw#Off = quadYaw# + 360.0;
else
quadYaw#Off = quadYaw#;
yawDifference# = quadYaw#Off - camYawDeg#Off;
cout << "Yaw# Offset Taken: " << yawDifference# << endl;
}
correctedYaw# = camYawDeg# + yawDifference#;
if(correctedYaw# > 180.0)
correctedYaw# -= 360.0;
else if(correctedYaw# < -180.0)
correctedYaw# += 360.0;
//===============END YAW CORRECTION=========================
#if USE_PRINTOUT
cout << "X: " << t.pos[0] << endl;
cout << "Y: " << t.pos[1] << endl;
cout << "Z: " << -t.pos[2] + 0.05 << endl;
#endif
#if USE_KEYBOARD
if (cflieCopter#->m_enumFlightMode == LANDING_MODE) //Landing Mode (TODO Change to be a keystroke when implemented)
{
//CORRECTS PITCH AND ROLL PID ERRORS TO ACCOUNT FOR QUADS CURRENT YAW DIRECTION
// xError# = cos(correctedYaw# / 57.2958)*(xPositionDesired# - xPosition#) - sin(correctedYaw# / 57.2958)*(yPositionDesired# - yPosition#);
// yError# = sin(correctedYaw# / 57.2958)*(xPositionDesired# - xPosition#) + cos(correctedYaw# / 57.2958)*(yPositionDesired# - yPosition#);
xError# = xPositionDesired# - xPosition#;
yError# = yPositionDesired# - yPosition#;
controllerSetXYError(&pidCtrl#, xError#, yError#);
controllerCorrectAttitudePID(&pidCtrl#, t.pos[0], t.pos[1], zPosition#, correctedYaw#,
xPositionDesired#, yPositionDesired#, -0.4, yawDesired#,
&rollControlOutput#, &pitchControlOutput#, &yawControlOutput#,
&thrustControlOutput#);
takeOff# = 0;
} else if (cflieCopter#->m_enumFlightMode == MIRROR_MODE) { //Acts as Master
xPositionDesired# = -0.012;
yPositionDesired# = -0.200;
zPositionDesired# = 0.75;
if( loopTime#Start - lastTime > 4.0 )
{
toggle = !toggle;
lastTime = loopTime#Start;
}
#if USE_PRINTOUT
cout << "New xPositionDesired: " << xPositionDesired# << endl;
#endif
if(toggle)
{
xStepPositionError# = xPositionDesired# - xPosition#;
yStepPositionError# = yPositionDesired# - yPosition#;
controllerSetXYError(&pidCtrl#, xStepPositionError#, yStepPositionError#);
controllerCorrectAttitudePID(&pidCtrl#, t.pos[0], t.pos[1], zPosition#, correctedYaw#,
xPositionDesired#, yPositionDesired#, zPositionDesired#,
yawDesired#, &rollControlOutput#, &pitchControlOutput#,
&yawControlOutput#, &thrustControlOutput#);
}
else
{
xStepPositionError# = (xPositionDesired# + 0.65) - xPosition#;
yStepPositionError# = (yPositionDesired# + 0.65) - yPosition#;
controllerSetXYError(&pidCtrl#, xStepPositionError#, yStepPositionError#);
controllerCorrectAttitudePID(&pidCtrl#, t.pos[0], t.pos[1], zPosition#, correctedYaw#,
xPositionDesired# + 0.65, yPositionDesired# + 0.65, zPositionDesired#,
yawDesired#, &rollControlOutput#, &pitchControlOutput#,
&yawControlOutput#, &thrustControlOutput#);
//cout << "Toggled!" << endl;
}
} else if (cflieCopter#->m_enumFlightMode == TAKEOFF_MODE) { //correctedYaw#
//CORRECTS PITCH AND ROLL PID ERRORS TO ACCOUNT FOR QUADS CURRENT YAW DIRECTION
// xError# = cos(correctedYaw# / 57.2958)*(xPositionDesired# - xPosition#) - sin(correctedYaw# / 57.2958)*(yPositionDesired# - yPosition#);
// yError# = sin(correctedYaw# / 57.2958)*(xPositionDesired# - xPosition#) + cos(correctedYaw# / 57.2958)*(yPositionDesired# - yPosition#);
xError# = xPositionDesired# - xPosition#;
yError# = yPositionDesired# - yPosition#;
controllerSetXYError(&pidCtrl#, xError#, yError#);
controllerCorrectAttitudePID(&pidCtrl#, t.pos[0], t.pos[1], zPosition#, correctedYaw#,
xPositionDesired#, yPositionDesired#, zPositionDesired#,
yawDesired#, &rollControlOutput#, &pitchControlOutput#,
&yawControlOutput#, &thrustControlOutput#);
}
else if (cflieCopter#->m_enumFlightMode == HAND_MODE) { //correctedYaw#
//CORRECTS PITCH AND ROLL PID ERRORS TO ACCOUNT FOR QUADS CURRENT YAW DIRECTION
// xError# = cos(correctedYaw# / 57.2958)*(xPositionDesired# - xPosition#) - sin(correctedYaw# / 57.2958)*(yPositionDesired# - yPosition#);
// yError# = sin(correctedYaw# / 57.2958)*(xPositionDesired# - xPosition#) + cos(correctedYaw# / 57.2958)*(yPositionDesired# - yPosition#);
xError# = (xPositionHand - 0.5) - xPosition#;
yError# = (yPositionHand + 0.5) - yPosition#;
controllerSetXYError(&pidCtrl#, xError#, yError#);
controllerCorrectAttitudePID(&pidCtrl#, t.pos[0], t.pos[1], zPosition#, correctedYaw#,
xPositionDesired#, yPositionDesired#, zPositionDesired#,
yawDesired#, &rollControlOutput#, &pitchControlOutput#,
&yawControlOutput#, &thrustControlOutput#);
}
else if(cflieCopter#->m_enumFlightMode == GROUNDED_MODE){
controllerResetAllPID(&pidCtrl#);
rollControlOutput# = 0;
pitchControlOutput# = 0;
yawControlOutput# = 0;
thrustControlOutput# = 0;
}
else{ //Emergency Case (Should never happen)
controllerResetAllPID(&pidCtrl#);
rollControlOutput# = 0;
pitchControlOutput# = 0;
yawControlOutput# = 0;
thrustControlOutput# = 0;
}
#else
controllerCorrectAttitudePID(&pidCtrl#, t.pos[0], t.pos[1], -t.pos[2], correctedYaw#,
xPositionDesired#, yPositionDesired#, zPositionDesired#,
yawDesired#, &rollControlOutput#, &pitchControlOutput#,
&yawControlOutput#, &thrustControlOutput#);
#endif
RunCrazyflie(crRadio(#RADIO NUM), cflieCopter#,
rollControlOutput#, pitchControlOutput#, yawControlOutput#, thrustControlOutput#);
#if USE_LOGGING
#if USE_BASIC_LOGGING
fprintf(out#, "%.6f\t\t", cflieCopter#->currentTime() - initTime# );
fprintf(out#, "%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.6f\t\t%.6f\t\t%.6f\t\t%.6f\t\t%.6f\t\t%.6f\t\t%d\t\t%d",
cflieCopter#->roll(),
cflieCopter#->pitch(),
quadYaw#,
t.pos[0],
t.pos[1],
-t.pos[2],
camYawDeg#,
correctedYaw#,
loopTimeTotal,
loopTimeTotalDelta,
loopTime#,
loopTime#Delta,
vrpnPacketDelta#,
vrpnPacketTime#,
vrpnPacketBackup#,
cflieCopter#->radioRSSI()); //
fprintf(out#, "\n");
#else
fprintf(out#, "%.6f\t\t", cflieCopter#->currentTime() - initTime# );
fprintf(out#, "%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.6f\t\t%.6f\t\t%.6f\t\t%.6f\t\t%.6f\t\t%.6f\t\t%d\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%d\t\t%.3f\t\t%.3f\t\t%.3f\t\t%lu\t\t%lu\t\t%lu\t\t%lu\t\t%.3f\t\t%.3f\t\t%.3f",
cflieCopter#->roll(),
cflieCopter#->pitch(),
quadYaw#,
t.pos[0],
t.pos[1],
-t.pos[2],
camYawDeg#,
correctedYaw#,
loopTimeTotal,
loopTimeTotalDelta,
loopTime#,
loopTime#Delta,
vrpnPacketDelta#,
vrpnPacketTime#,
vrpnPacketBackup#,
xPositionDesired#,
yPositionDesired#,
zPositionDesired#,
yawDesired#,
pitchControlOutput#,
rollControlOutput#,
yawControlOutput#,
thrustControlOutput#,
cflieCopter#->radioRSSI(),
euler[0],
euler[1],
euler[2],
cflieCopter#->motor1(),
cflieCopter#->motor2(),
cflieCopter#->motor3(),
cflieCopter#->motor4(),
cflieCopter#->gyroX(),
cflieCopter#->gyroY(),
cflieCopter#->gyroZ()); //
fprintf(out#, "\n");
#endif
#endif
loopTime#End = cflieCopter#->currentTime() - initTime#;
loopTime# = loopTime#End - loopTime#Start;
} //End Packet Backup If check
else if(vrpnPacketBackup# < 0){ //Failsafe so can't go below 0 (should never happen) | || (vrpnPacketBackup# > 20)?
vrpnPacketBackup# = 0;
// RunCrazyflie(crRadio(#RADIO NUM), cflieCopter#,
// rollControlOutput#, pitchControlOutput#, yawControlOutput#, thrustControlOutput#);
}
else if(vrpnPacketBackup# >= 2){
// cout << "VRPN Packet Backup # Detected: " << vrpnPacketBackup# << endl;
vrpnPacketBackup# --;
// RunCrazyflie(crRadio(#RADIO NUM), cflieCopter#,
// rollControlOutput#, pitchControlOutput#, yawControlOutput#, thrustControlOutput#);
}//End Packet Backup Purge
} //END CALLBACK #
</pre>
</code>
</blockquote>
----
<center> '''Main Directory''' </center>
<center> [[Crazyflie Swarm|Crazyflie Swarm Home]] | [[PC Client Software]] | [[USB Radio]] | [[Firmware]] | [[FAQ]] </center>
<center> '''Modifications Directory''' </center>
<center> [[Controller]] | [[Logging]] | [[Keyboard Commands]] | [[USB Radio#Changing Radio Channel|Changing Radio Channel]] | [[Flight Modes]] | [[Callbacks]] | [[Adding a Crazyflie]] | [[Firmware]] </center>
0321f11a2699e6da8d309359603f176e16fec31d
156
155
2016-07-28T17:52:37Z
Jnoronha
3
/* Creating a New Callback */ change list to numbered list
wikitext
text/x-wiki
Adding a Crazyflie to the Swarm is simple, but tedious. It's basically just replicating a copy of the other Crazyflies code, but there are multiple files you will need to make changes in. The following list should help you locate all the code you need to replicate:
==Changes in ''vrpn.cpp''==
<blockquote>
<code>
<pre>
vrpn_Tracker_Remote *tracker#;
extern float xPositionDesired#;
extern float yPositionDesired#;
extern float zPositionDesired#;
extern float yawDesired#;
extern float xPosition#;
extern float yPosition#;
extern float zPosition#;
extern CCrazyflie *cflieCopter#;
extern double initTime#;
extern char takeOff#;
extern double takeOffTime#;
void vrpn_init(std::string connectionName, void (*callback)(void*, const vrpn_TRACKERCB),
void (*callback2)(void*, const vrpn_TRACKERCB), void (*callback#)(void*, const vrpn_TRACKERCB), ......, char *key) {
tracker# = new vrpn_Tracker_Remote("Crazyflie2#", connection);
tracker#->register_change_handler(0, callback#);
tracker#->mainloop();
</pre>
</code>
</blockquote>
===Changes in ''nearGround()''===
<blockquote>
<code>
<pre>
void nearGround() //During Landing Mode checks how close to ground quad is for shutdown
{
...
...
...
if(cflieCopter#){
if((cflieCopter#->m_enumFlightMode == LANDING_MODE) && (zPosition# < 0.05))
{
cflieCopter#->m_enumFlightMode = GROUNDED_MODE;
}
}
}
</pre>
</code>
</blockquote>
===Changes in ''updateHand()''===
<blockquote>
<code>
<pre>
void updateHand()
{
if(handMode == 1)
{
// cout << "Hand Roll: " << rollHand << endl;
if(killCount > 5){
...
...
cflieCopter#->m_enumFlightMode = GROUNDED_MODE;
}
else if(trackCount > 5){
...
...
cflieCopter#->m_enumFlightMode = HAND_MODE;
}
else{
...
...
if(zPositionHand > 1.6)
{
...
...
cflieCopter#->m_enumFlightMode = TAKEOFF_MODE;
cout << "Hand Mode: Launching Quads" << endl;
}
else if(zPositionHand < 0.4)
{
...
...
cflieCopter#->m_enumFlightMode = LANDING_MODE;
...
}
}
}
}
</pre>
</code>
</blockquote>
==Changes in ''vrpn.h''==
<blockquote>
<code>
<pre>
void vrpn_init(std::string connectionName, void (*callback)(void*, const vrpn_TRACKERCB),
void (*callback2)(void*, const vrpn_TRACKERCB), void (*callback#)(void*, const vrpn_TRACKERCB), ...., char *key);
</pre>
</code>
</blockquote>
==Changes in ''eris_vrpn.cpp''==
===Global Variables===
<blockquote>
<code>
<pre>
void VRPN_CALLBACK handle_Crazyflie#(void*, const vrpn_TRACKERCB t);
CCrazyRadio *crRadio# = 0; //***NOT NECESSARY IF LESS THAN 3 QUADS PER RADIO***
CCrazyflie *cflieCopter# = 0;
ControllerObject pidCtrl# = { 0 }; // init all fields to zero
float rollControlOutput#;
float pitchControlOutput#;
float yawControlOutput#;
float thrustControlOutput#;
double initTime# = 0;
int vrpnPacketBackup# = 0;
double vrpnBackupTime# = 0;
double vrpnBackupTime#Prev = 0;
double vrpnBackupTime#Delta = 0;
float xPositionDesired# = 0.681;
float yPositionDesired# = 0.129;
float zPositionDesired# = 0.6;
float yawDesired# = -90.0;
float yawDifference# = 0;
float quadYaw# = 0;
float prevQuadYaw# = 0;
float camYawDeg# = 0;
float camYawDeg#Off = 0;
float quadYaw#Off = 0;
float correctedYaw# = 0;
float xError# = 0.0;
float yError# = 0.0;
float xStepPositionError# = 0.0;
float yStepPositionError# = 0.0;
float xPosition# = -0.012;
float yPosition# = -0.008; //Default Crazyflie location setpoints
float zPosition# = 0.75;
char takeOff# = 0;
double loopTime#Start = 0;
double loopTime#End = 0;
double loopTime# = 0;
double loopTime#Prev = 0;
double loopTime#Delta = 0;
double vrpnPacketTime# = 0;
double vrpnPacketTime#Prev = 0;
double vrpnPacketDelta# = 0;
FILE * out# = NULL;
</pre>
</code>
</blockquote>
===Changes in ''main()''===
<blockquote>
<code>
<pre>
controllerResetAllPID( &pidCtrl# );
controllerInit( &pidCtrl# );
vrpn_init("192.168.0.120:3883", handle_pos, handle_Crazyflie2, handle_Crazyflie#, handle_Crazyflie(#+1), ..., &keystroke_now);
cflieCopter# = new CCrazyflie(crRadio(radio dongle number), (Radio Channel));
const char * logHeader# = "#Crazyflie# Log File\n\
#Time\t\t........
if(cflieCopter#)
{
out# = fopen("cflie#.txt", "w");
if(out# == NULL)
{
printf("Could not open cflie#.log:errno %d\n", errno);
exit(-1);
}
fprintf(out#, "%s\n", logHeader#);
}
crRadio#->setARDTime(2000); //Sets Wait Time between Packet Retries (**MUST BE IN INCREMENTS OF 250**)
crRadio#->setARC(0); //Sets Number of times Retries Packet Send
crRadio#->setPower(P_0DBM);
cflieCopter#->setSendSetpoints( true );
initTime# = cflieCopter#->currentTime();
cflieCopter#->m_enumFlightMode = GROUNDED_MODE;
fclose(out#);
delete cflieCopter#;
delete crRadio#;
</pre>
</code>
</blockquote>
==Creating a New Callback==
'''Note:''' To make it easier for this section you can:
#COPY and PASTE the callback code directly after the last callback in the Swarm Client
#Use FIND and REPLACE to replace all '#' signs with the Crazyflie number desired
:*'''IMPORTANT:''' Be careful, some of the '#' symbols are used for the Radio Dongle number also.
<blockquote>
<code>
<pre>
void VRPN_CALLBACK handle_Crazyflie#(void*, const vrpn_TRACKERCB t) {
if(vrpnPacketBackup# < 2) //If VRPN Buffer does NOT have old packets stored up, run main code
{
loopTime#Start = cflieCopter#->currentTime() - initTime#;
loopTime#Delta = loopTime#Start - loopTime#Prev; //Calculates time difference between each loop start
loopTime#Prev = loopTime#Start;
vrpnPacketTime# = t.msg_time.tv_sec + (t.msg_time.tv_usec / 1000000.0);
vrpnPacketDelta# = vrpnPacketTime# - vrpnPacketTime#Prev;
vrpnPacketTime#Prev = vrpnPacketTime#;
vrpnPacketBackup# = ceil(loopTime#Delta/vrpnPacketDelta#); //Calculates estimated # of packets built up in VRPN buffer.
controllerSetAllDt(&pidCtrl#, vrpnPacketDelta#); //Variable dt for controller based on time between packets | vrpnPacketDelta2
cflieCopter1->cheat_process_packets(); //Flush out other Copter Packets
crRadio(#RADIO NUM)->clearPackets();
crRadio(#RADIO NUM)->setChannel( cflieCopter#->radioChannel() );
frameCount++;
// Get the euler angles
q_vec_type euler;
q_to_euler(euler, t.quat);
xPosition# = t.pos[0];
yPosition# = t.pos[1]; //Stores X, Y, and Z Position for use in other Callbacks (external)
zPosition# = -t.pos[2] + 0.05;
#if USE_PRINTOUT
cout << "PID Radio #" << endl << endl;
#endif
#if 0 //UNUSED (old way of storing camera data)
//cout << "\033[2J\033[1;1H"; //Clears Terminal Window to display clean output
cfliePitch = cflieCopter#->pitch();
cflieRoll = cflieCopter#->roll();
cflieYaw = cflieCopter#->yaw();
cflieThrust = cflieCopter#->thrust();
/*
* Position
* x t.pos[0]
* y t.pos[1]
* z t.pos[2]
*
* Orientation
* yaw euler[0] Rotation
* pitch euler[1] East-West movement
* roll euler[2] North-South movement
* Euler's range goes from -pi : +pi
*/
QUAD quad;
quad.vrpnNow = 0;
vrpn_data_t *vrpnData;
vrpnData = (vrpn_data_t*) malloc(sizeof(vrpn_data_t));
vrpnData->usec = t.msg_time.tv_sec + (t.msg_time.tv_usec / 1000000.0);
vrpnData->x = t.pos[0];
vrpnData->y = t.pos[1];
vrpnData->z = -t.pos[2] + 0.05; //Higher Altitude = Negative z //Added Offset for floor below camera system origin
vrpnData->yaw = euler[0];
vrpnData->pitch = euler[1];
vrpnData->roll = euler[2];
xPosition# = t.pos[0];
yPosition# = t.pos[1];
zPosition# = -t.pos[2] + 0.05;
cout << "xPosition of Crazyflie#: " << xPosition# << endl;
quad.vrpnPrev = quad.vrpnNow;
if (quad.vrpnNow == 0) {
quad.vrpnPrev = 0;
quad.vrpnTime0 = vrpnData->usec;
quad.vrpnNow = vrpnData->usec;
} else {
quad.vrpnNow = vrpnData->usec - quad.vrpnTime0;
}
#endif //END UNUSED
//==============YAW CORRECTION========================= (IMPORTANT!!!: YAW CONTROLLER INPUT IS INVERTED IN simple.cpp FILE***)
camYawDeg# = -(euler[0] * 57.2958); //Converts From Radians TO Degrees
quadYaw# = cflieCopter#->yaw();
if (frameCount == 50) {
if (camYawDeg# < 0.0)
camYawDeg#Off = camYawDeg# + 360.0; //Converts from +-180 to full 360 degree form
else
camYawDeg#Off = camYawDeg#;
if(quadYaw# < 0.0)
quadYaw#Off = quadYaw# + 360.0;
else
quadYaw#Off = quadYaw#;
yawDifference# = quadYaw#Off - camYawDeg#Off;
cout << "Yaw# Offset Taken: " << yawDifference# << endl;
}
correctedYaw# = camYawDeg# + yawDifference#;
if(correctedYaw# > 180.0)
correctedYaw# -= 360.0;
else if(correctedYaw# < -180.0)
correctedYaw# += 360.0;
//===============END YAW CORRECTION=========================
#if USE_PRINTOUT
cout << "X: " << t.pos[0] << endl;
cout << "Y: " << t.pos[1] << endl;
cout << "Z: " << -t.pos[2] + 0.05 << endl;
#endif
#if USE_KEYBOARD
if (cflieCopter#->m_enumFlightMode == LANDING_MODE) //Landing Mode (TODO Change to be a keystroke when implemented)
{
//CORRECTS PITCH AND ROLL PID ERRORS TO ACCOUNT FOR QUADS CURRENT YAW DIRECTION
// xError# = cos(correctedYaw# / 57.2958)*(xPositionDesired# - xPosition#) - sin(correctedYaw# / 57.2958)*(yPositionDesired# - yPosition#);
// yError# = sin(correctedYaw# / 57.2958)*(xPositionDesired# - xPosition#) + cos(correctedYaw# / 57.2958)*(yPositionDesired# - yPosition#);
xError# = xPositionDesired# - xPosition#;
yError# = yPositionDesired# - yPosition#;
controllerSetXYError(&pidCtrl#, xError#, yError#);
controllerCorrectAttitudePID(&pidCtrl#, t.pos[0], t.pos[1], zPosition#, correctedYaw#,
xPositionDesired#, yPositionDesired#, -0.4, yawDesired#,
&rollControlOutput#, &pitchControlOutput#, &yawControlOutput#,
&thrustControlOutput#);
takeOff# = 0;
} else if (cflieCopter#->m_enumFlightMode == MIRROR_MODE) { //Acts as Master
xPositionDesired# = -0.012;
yPositionDesired# = -0.200;
zPositionDesired# = 0.75;
if( loopTime#Start - lastTime > 4.0 )
{
toggle = !toggle;
lastTime = loopTime#Start;
}
#if USE_PRINTOUT
cout << "New xPositionDesired: " << xPositionDesired# << endl;
#endif
if(toggle)
{
xStepPositionError# = xPositionDesired# - xPosition#;
yStepPositionError# = yPositionDesired# - yPosition#;
controllerSetXYError(&pidCtrl#, xStepPositionError#, yStepPositionError#);
controllerCorrectAttitudePID(&pidCtrl#, t.pos[0], t.pos[1], zPosition#, correctedYaw#,
xPositionDesired#, yPositionDesired#, zPositionDesired#,
yawDesired#, &rollControlOutput#, &pitchControlOutput#,
&yawControlOutput#, &thrustControlOutput#);
}
else
{
xStepPositionError# = (xPositionDesired# + 0.65) - xPosition#;
yStepPositionError# = (yPositionDesired# + 0.65) - yPosition#;
controllerSetXYError(&pidCtrl#, xStepPositionError#, yStepPositionError#);
controllerCorrectAttitudePID(&pidCtrl#, t.pos[0], t.pos[1], zPosition#, correctedYaw#,
xPositionDesired# + 0.65, yPositionDesired# + 0.65, zPositionDesired#,
yawDesired#, &rollControlOutput#, &pitchControlOutput#,
&yawControlOutput#, &thrustControlOutput#);
//cout << "Toggled!" << endl;
}
} else if (cflieCopter#->m_enumFlightMode == TAKEOFF_MODE) { //correctedYaw#
//CORRECTS PITCH AND ROLL PID ERRORS TO ACCOUNT FOR QUADS CURRENT YAW DIRECTION
// xError# = cos(correctedYaw# / 57.2958)*(xPositionDesired# - xPosition#) - sin(correctedYaw# / 57.2958)*(yPositionDesired# - yPosition#);
// yError# = sin(correctedYaw# / 57.2958)*(xPositionDesired# - xPosition#) + cos(correctedYaw# / 57.2958)*(yPositionDesired# - yPosition#);
xError# = xPositionDesired# - xPosition#;
yError# = yPositionDesired# - yPosition#;
controllerSetXYError(&pidCtrl#, xError#, yError#);
controllerCorrectAttitudePID(&pidCtrl#, t.pos[0], t.pos[1], zPosition#, correctedYaw#,
xPositionDesired#, yPositionDesired#, zPositionDesired#,
yawDesired#, &rollControlOutput#, &pitchControlOutput#,
&yawControlOutput#, &thrustControlOutput#);
}
else if (cflieCopter#->m_enumFlightMode == HAND_MODE) { //correctedYaw#
//CORRECTS PITCH AND ROLL PID ERRORS TO ACCOUNT FOR QUADS CURRENT YAW DIRECTION
// xError# = cos(correctedYaw# / 57.2958)*(xPositionDesired# - xPosition#) - sin(correctedYaw# / 57.2958)*(yPositionDesired# - yPosition#);
// yError# = sin(correctedYaw# / 57.2958)*(xPositionDesired# - xPosition#) + cos(correctedYaw# / 57.2958)*(yPositionDesired# - yPosition#);
xError# = (xPositionHand - 0.5) - xPosition#;
yError# = (yPositionHand + 0.5) - yPosition#;
controllerSetXYError(&pidCtrl#, xError#, yError#);
controllerCorrectAttitudePID(&pidCtrl#, t.pos[0], t.pos[1], zPosition#, correctedYaw#,
xPositionDesired#, yPositionDesired#, zPositionDesired#,
yawDesired#, &rollControlOutput#, &pitchControlOutput#,
&yawControlOutput#, &thrustControlOutput#);
}
else if(cflieCopter#->m_enumFlightMode == GROUNDED_MODE){
controllerResetAllPID(&pidCtrl#);
rollControlOutput# = 0;
pitchControlOutput# = 0;
yawControlOutput# = 0;
thrustControlOutput# = 0;
}
else{ //Emergency Case (Should never happen)
controllerResetAllPID(&pidCtrl#);
rollControlOutput# = 0;
pitchControlOutput# = 0;
yawControlOutput# = 0;
thrustControlOutput# = 0;
}
#else
controllerCorrectAttitudePID(&pidCtrl#, t.pos[0], t.pos[1], -t.pos[2], correctedYaw#,
xPositionDesired#, yPositionDesired#, zPositionDesired#,
yawDesired#, &rollControlOutput#, &pitchControlOutput#,
&yawControlOutput#, &thrustControlOutput#);
#endif
RunCrazyflie(crRadio(#RADIO NUM), cflieCopter#,
rollControlOutput#, pitchControlOutput#, yawControlOutput#, thrustControlOutput#);
#if USE_LOGGING
#if USE_BASIC_LOGGING
fprintf(out#, "%.6f\t\t", cflieCopter#->currentTime() - initTime# );
fprintf(out#, "%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.6f\t\t%.6f\t\t%.6f\t\t%.6f\t\t%.6f\t\t%.6f\t\t%d\t\t%d",
cflieCopter#->roll(),
cflieCopter#->pitch(),
quadYaw#,
t.pos[0],
t.pos[1],
-t.pos[2],
camYawDeg#,
correctedYaw#,
loopTimeTotal,
loopTimeTotalDelta,
loopTime#,
loopTime#Delta,
vrpnPacketDelta#,
vrpnPacketTime#,
vrpnPacketBackup#,
cflieCopter#->radioRSSI()); //
fprintf(out#, "\n");
#else
fprintf(out#, "%.6f\t\t", cflieCopter#->currentTime() - initTime# );
fprintf(out#, "%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.6f\t\t%.6f\t\t%.6f\t\t%.6f\t\t%.6f\t\t%.6f\t\t%d\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%d\t\t%.3f\t\t%.3f\t\t%.3f\t\t%lu\t\t%lu\t\t%lu\t\t%lu\t\t%.3f\t\t%.3f\t\t%.3f",
cflieCopter#->roll(),
cflieCopter#->pitch(),
quadYaw#,
t.pos[0],
t.pos[1],
-t.pos[2],
camYawDeg#,
correctedYaw#,
loopTimeTotal,
loopTimeTotalDelta,
loopTime#,
loopTime#Delta,
vrpnPacketDelta#,
vrpnPacketTime#,
vrpnPacketBackup#,
xPositionDesired#,
yPositionDesired#,
zPositionDesired#,
yawDesired#,
pitchControlOutput#,
rollControlOutput#,
yawControlOutput#,
thrustControlOutput#,
cflieCopter#->radioRSSI(),
euler[0],
euler[1],
euler[2],
cflieCopter#->motor1(),
cflieCopter#->motor2(),
cflieCopter#->motor3(),
cflieCopter#->motor4(),
cflieCopter#->gyroX(),
cflieCopter#->gyroY(),
cflieCopter#->gyroZ()); //
fprintf(out#, "\n");
#endif
#endif
loopTime#End = cflieCopter#->currentTime() - initTime#;
loopTime# = loopTime#End - loopTime#Start;
} //End Packet Backup If check
else if(vrpnPacketBackup# < 0){ //Failsafe so can't go below 0 (should never happen) | || (vrpnPacketBackup# > 20)?
vrpnPacketBackup# = 0;
// RunCrazyflie(crRadio(#RADIO NUM), cflieCopter#,
// rollControlOutput#, pitchControlOutput#, yawControlOutput#, thrustControlOutput#);
}
else if(vrpnPacketBackup# >= 2){
// cout << "VRPN Packet Backup # Detected: " << vrpnPacketBackup# << endl;
vrpnPacketBackup# --;
// RunCrazyflie(crRadio(#RADIO NUM), cflieCopter#,
// rollControlOutput#, pitchControlOutput#, yawControlOutput#, thrustControlOutput#);
}//End Packet Backup Purge
} //END CALLBACK #
</pre>
</code>
</blockquote>
----
<center> '''Main Directory''' </center>
<center> [[Crazyflie Swarm|Crazyflie Swarm Home]] | [[PC Client Software]] | [[USB Radio]] | [[Firmware]] | [[FAQ]] </center>
<center> '''Modifications Directory''' </center>
<center> [[Controller]] | [[Logging]] | [[Keyboard Commands]] | [[USB Radio#Changing Radio Channel|Changing Radio Channel]] | [[Flight Modes]] | [[Callbacks]] | [[Adding a Crazyflie]] | [[Firmware]] </center>
2194f1b889d2487f97ae72c46eeacc9fd6d3cdda
157
156
2016-07-28T17:53:31Z
Jnoronha
3
Added ctrl+c handler section
wikitext
text/x-wiki
Adding a Crazyflie to the Swarm is simple, but tedious. It's basically just replicating a copy of the other Crazyflies code, but there are multiple files you will need to make changes in. The following list should help you locate all the code you need to replicate:
==Changes in ''vrpn.cpp''==
<blockquote>
<code>
<pre>
vrpn_Tracker_Remote *tracker#;
extern float xPositionDesired#;
extern float yPositionDesired#;
extern float zPositionDesired#;
extern float yawDesired#;
extern float xPosition#;
extern float yPosition#;
extern float zPosition#;
extern CCrazyflie *cflieCopter#;
extern double initTime#;
extern char takeOff#;
extern double takeOffTime#;
void vrpn_init(std::string connectionName, void (*callback)(void*, const vrpn_TRACKERCB),
void (*callback2)(void*, const vrpn_TRACKERCB), void (*callback#)(void*, const vrpn_TRACKERCB), ......, char *key) {
tracker# = new vrpn_Tracker_Remote("Crazyflie2#", connection);
tracker#->register_change_handler(0, callback#);
tracker#->mainloop();
</pre>
</code>
</blockquote>
===Changes in ''nearGround()''===
<blockquote>
<code>
<pre>
void nearGround() //During Landing Mode checks how close to ground quad is for shutdown
{
...
...
...
if(cflieCopter#){
if((cflieCopter#->m_enumFlightMode == LANDING_MODE) && (zPosition# < 0.05))
{
cflieCopter#->m_enumFlightMode = GROUNDED_MODE;
}
}
}
</pre>
</code>
</blockquote>
===Changes in ''updateHand()''===
<blockquote>
<code>
<pre>
void updateHand()
{
if(handMode == 1)
{
// cout << "Hand Roll: " << rollHand << endl;
if(killCount > 5){
...
...
cflieCopter#->m_enumFlightMode = GROUNDED_MODE;
}
else if(trackCount > 5){
...
...
cflieCopter#->m_enumFlightMode = HAND_MODE;
}
else{
...
...
if(zPositionHand > 1.6)
{
...
...
cflieCopter#->m_enumFlightMode = TAKEOFF_MODE;
cout << "Hand Mode: Launching Quads" << endl;
}
else if(zPositionHand < 0.4)
{
...
...
cflieCopter#->m_enumFlightMode = LANDING_MODE;
...
}
}
}
}
</pre>
</code>
</blockquote>
==Changes in ''vrpn.h''==
<blockquote>
<code>
<pre>
void vrpn_init(std::string connectionName, void (*callback)(void*, const vrpn_TRACKERCB),
void (*callback2)(void*, const vrpn_TRACKERCB), void (*callback#)(void*, const vrpn_TRACKERCB), ...., char *key);
</pre>
</code>
</blockquote>
==Changes in ''eris_vrpn.cpp''==
===Global Variables===
<blockquote>
<code>
<pre>
void VRPN_CALLBACK handle_Crazyflie#(void*, const vrpn_TRACKERCB t);
CCrazyRadio *crRadio# = 0; //***NOT NECESSARY IF LESS THAN 3 QUADS PER RADIO***
CCrazyflie *cflieCopter# = 0;
ControllerObject pidCtrl# = { 0 }; // init all fields to zero
float rollControlOutput#;
float pitchControlOutput#;
float yawControlOutput#;
float thrustControlOutput#;
double initTime# = 0;
int vrpnPacketBackup# = 0;
double vrpnBackupTime# = 0;
double vrpnBackupTime#Prev = 0;
double vrpnBackupTime#Delta = 0;
float xPositionDesired# = 0.681;
float yPositionDesired# = 0.129;
float zPositionDesired# = 0.6;
float yawDesired# = -90.0;
float yawDifference# = 0;
float quadYaw# = 0;
float prevQuadYaw# = 0;
float camYawDeg# = 0;
float camYawDeg#Off = 0;
float quadYaw#Off = 0;
float correctedYaw# = 0;
float xError# = 0.0;
float yError# = 0.0;
float xStepPositionError# = 0.0;
float yStepPositionError# = 0.0;
float xPosition# = -0.012;
float yPosition# = -0.008; //Default Crazyflie location setpoints
float zPosition# = 0.75;
char takeOff# = 0;
double loopTime#Start = 0;
double loopTime#End = 0;
double loopTime# = 0;
double loopTime#Prev = 0;
double loopTime#Delta = 0;
double vrpnPacketTime# = 0;
double vrpnPacketTime#Prev = 0;
double vrpnPacketDelta# = 0;
FILE * out# = NULL;
</pre>
</code>
</blockquote>
===Changes in ''main()''===
<blockquote>
<code>
<pre>
controllerResetAllPID( &pidCtrl# );
controllerInit( &pidCtrl# );
vrpn_init("192.168.0.120:3883", handle_pos, handle_Crazyflie2, handle_Crazyflie#, handle_Crazyflie(#+1), ..., &keystroke_now);
cflieCopter# = new CCrazyflie(crRadio(radio dongle number), (Radio Channel));
const char * logHeader# = "#Crazyflie# Log File\n\
#Time\t\t........
if(cflieCopter#)
{
out# = fopen("cflie#.txt", "w");
if(out# == NULL)
{
printf("Could not open cflie#.log:errno %d\n", errno);
exit(-1);
}
fprintf(out#, "%s\n", logHeader#);
}
crRadio#->setARDTime(2000); //Sets Wait Time between Packet Retries (**MUST BE IN INCREMENTS OF 250**)
crRadio#->setARC(0); //Sets Number of times Retries Packet Send
crRadio#->setPower(P_0DBM);
cflieCopter#->setSendSetpoints( true );
initTime# = cflieCopter#->currentTime();
cflieCopter#->m_enumFlightMode = GROUNDED_MODE;
fclose(out#);
delete cflieCopter#;
delete crRadio#;
</pre>
</code>
</blockquote>
==Creating a New Callback==
'''Note:''' To make it easier for this section you can:
#COPY and PASTE the callback code directly after the last callback in the Swarm Client
#Use FIND and REPLACE to replace all '#' signs with the Crazyflie number desired
:*'''IMPORTANT:''' Be careful, some of the '#' symbols are used for the Radio Dongle number also.
<blockquote>
<code>
<pre>
void VRPN_CALLBACK handle_Crazyflie#(void*, const vrpn_TRACKERCB t) {
if(vrpnPacketBackup# < 2) //If VRPN Buffer does NOT have old packets stored up, run main code
{
loopTime#Start = cflieCopter#->currentTime() - initTime#;
loopTime#Delta = loopTime#Start - loopTime#Prev; //Calculates time difference between each loop start
loopTime#Prev = loopTime#Start;
vrpnPacketTime# = t.msg_time.tv_sec + (t.msg_time.tv_usec / 1000000.0);
vrpnPacketDelta# = vrpnPacketTime# - vrpnPacketTime#Prev;
vrpnPacketTime#Prev = vrpnPacketTime#;
vrpnPacketBackup# = ceil(loopTime#Delta/vrpnPacketDelta#); //Calculates estimated # of packets built up in VRPN buffer.
controllerSetAllDt(&pidCtrl#, vrpnPacketDelta#); //Variable dt for controller based on time between packets | vrpnPacketDelta2
cflieCopter1->cheat_process_packets(); //Flush out other Copter Packets
crRadio(#RADIO NUM)->clearPackets();
crRadio(#RADIO NUM)->setChannel( cflieCopter#->radioChannel() );
frameCount++;
// Get the euler angles
q_vec_type euler;
q_to_euler(euler, t.quat);
xPosition# = t.pos[0];
yPosition# = t.pos[1]; //Stores X, Y, and Z Position for use in other Callbacks (external)
zPosition# = -t.pos[2] + 0.05;
#if USE_PRINTOUT
cout << "PID Radio #" << endl << endl;
#endif
#if 0 //UNUSED (old way of storing camera data)
//cout << "\033[2J\033[1;1H"; //Clears Terminal Window to display clean output
cfliePitch = cflieCopter#->pitch();
cflieRoll = cflieCopter#->roll();
cflieYaw = cflieCopter#->yaw();
cflieThrust = cflieCopter#->thrust();
/*
* Position
* x t.pos[0]
* y t.pos[1]
* z t.pos[2]
*
* Orientation
* yaw euler[0] Rotation
* pitch euler[1] East-West movement
* roll euler[2] North-South movement
* Euler's range goes from -pi : +pi
*/
QUAD quad;
quad.vrpnNow = 0;
vrpn_data_t *vrpnData;
vrpnData = (vrpn_data_t*) malloc(sizeof(vrpn_data_t));
vrpnData->usec = t.msg_time.tv_sec + (t.msg_time.tv_usec / 1000000.0);
vrpnData->x = t.pos[0];
vrpnData->y = t.pos[1];
vrpnData->z = -t.pos[2] + 0.05; //Higher Altitude = Negative z //Added Offset for floor below camera system origin
vrpnData->yaw = euler[0];
vrpnData->pitch = euler[1];
vrpnData->roll = euler[2];
xPosition# = t.pos[0];
yPosition# = t.pos[1];
zPosition# = -t.pos[2] + 0.05;
cout << "xPosition of Crazyflie#: " << xPosition# << endl;
quad.vrpnPrev = quad.vrpnNow;
if (quad.vrpnNow == 0) {
quad.vrpnPrev = 0;
quad.vrpnTime0 = vrpnData->usec;
quad.vrpnNow = vrpnData->usec;
} else {
quad.vrpnNow = vrpnData->usec - quad.vrpnTime0;
}
#endif //END UNUSED
//==============YAW CORRECTION========================= (IMPORTANT!!!: YAW CONTROLLER INPUT IS INVERTED IN simple.cpp FILE***)
camYawDeg# = -(euler[0] * 57.2958); //Converts From Radians TO Degrees
quadYaw# = cflieCopter#->yaw();
if (frameCount == 50) {
if (camYawDeg# < 0.0)
camYawDeg#Off = camYawDeg# + 360.0; //Converts from +-180 to full 360 degree form
else
camYawDeg#Off = camYawDeg#;
if(quadYaw# < 0.0)
quadYaw#Off = quadYaw# + 360.0;
else
quadYaw#Off = quadYaw#;
yawDifference# = quadYaw#Off - camYawDeg#Off;
cout << "Yaw# Offset Taken: " << yawDifference# << endl;
}
correctedYaw# = camYawDeg# + yawDifference#;
if(correctedYaw# > 180.0)
correctedYaw# -= 360.0;
else if(correctedYaw# < -180.0)
correctedYaw# += 360.0;
//===============END YAW CORRECTION=========================
#if USE_PRINTOUT
cout << "X: " << t.pos[0] << endl;
cout << "Y: " << t.pos[1] << endl;
cout << "Z: " << -t.pos[2] + 0.05 << endl;
#endif
#if USE_KEYBOARD
if (cflieCopter#->m_enumFlightMode == LANDING_MODE) //Landing Mode (TODO Change to be a keystroke when implemented)
{
//CORRECTS PITCH AND ROLL PID ERRORS TO ACCOUNT FOR QUADS CURRENT YAW DIRECTION
// xError# = cos(correctedYaw# / 57.2958)*(xPositionDesired# - xPosition#) - sin(correctedYaw# / 57.2958)*(yPositionDesired# - yPosition#);
// yError# = sin(correctedYaw# / 57.2958)*(xPositionDesired# - xPosition#) + cos(correctedYaw# / 57.2958)*(yPositionDesired# - yPosition#);
xError# = xPositionDesired# - xPosition#;
yError# = yPositionDesired# - yPosition#;
controllerSetXYError(&pidCtrl#, xError#, yError#);
controllerCorrectAttitudePID(&pidCtrl#, t.pos[0], t.pos[1], zPosition#, correctedYaw#,
xPositionDesired#, yPositionDesired#, -0.4, yawDesired#,
&rollControlOutput#, &pitchControlOutput#, &yawControlOutput#,
&thrustControlOutput#);
takeOff# = 0;
} else if (cflieCopter#->m_enumFlightMode == MIRROR_MODE) { //Acts as Master
xPositionDesired# = -0.012;
yPositionDesired# = -0.200;
zPositionDesired# = 0.75;
if( loopTime#Start - lastTime > 4.0 )
{
toggle = !toggle;
lastTime = loopTime#Start;
}
#if USE_PRINTOUT
cout << "New xPositionDesired: " << xPositionDesired# << endl;
#endif
if(toggle)
{
xStepPositionError# = xPositionDesired# - xPosition#;
yStepPositionError# = yPositionDesired# - yPosition#;
controllerSetXYError(&pidCtrl#, xStepPositionError#, yStepPositionError#);
controllerCorrectAttitudePID(&pidCtrl#, t.pos[0], t.pos[1], zPosition#, correctedYaw#,
xPositionDesired#, yPositionDesired#, zPositionDesired#,
yawDesired#, &rollControlOutput#, &pitchControlOutput#,
&yawControlOutput#, &thrustControlOutput#);
}
else
{
xStepPositionError# = (xPositionDesired# + 0.65) - xPosition#;
yStepPositionError# = (yPositionDesired# + 0.65) - yPosition#;
controllerSetXYError(&pidCtrl#, xStepPositionError#, yStepPositionError#);
controllerCorrectAttitudePID(&pidCtrl#, t.pos[0], t.pos[1], zPosition#, correctedYaw#,
xPositionDesired# + 0.65, yPositionDesired# + 0.65, zPositionDesired#,
yawDesired#, &rollControlOutput#, &pitchControlOutput#,
&yawControlOutput#, &thrustControlOutput#);
//cout << "Toggled!" << endl;
}
} else if (cflieCopter#->m_enumFlightMode == TAKEOFF_MODE) { //correctedYaw#
//CORRECTS PITCH AND ROLL PID ERRORS TO ACCOUNT FOR QUADS CURRENT YAW DIRECTION
// xError# = cos(correctedYaw# / 57.2958)*(xPositionDesired# - xPosition#) - sin(correctedYaw# / 57.2958)*(yPositionDesired# - yPosition#);
// yError# = sin(correctedYaw# / 57.2958)*(xPositionDesired# - xPosition#) + cos(correctedYaw# / 57.2958)*(yPositionDesired# - yPosition#);
xError# = xPositionDesired# - xPosition#;
yError# = yPositionDesired# - yPosition#;
controllerSetXYError(&pidCtrl#, xError#, yError#);
controllerCorrectAttitudePID(&pidCtrl#, t.pos[0], t.pos[1], zPosition#, correctedYaw#,
xPositionDesired#, yPositionDesired#, zPositionDesired#,
yawDesired#, &rollControlOutput#, &pitchControlOutput#,
&yawControlOutput#, &thrustControlOutput#);
}
else if (cflieCopter#->m_enumFlightMode == HAND_MODE) { //correctedYaw#
//CORRECTS PITCH AND ROLL PID ERRORS TO ACCOUNT FOR QUADS CURRENT YAW DIRECTION
// xError# = cos(correctedYaw# / 57.2958)*(xPositionDesired# - xPosition#) - sin(correctedYaw# / 57.2958)*(yPositionDesired# - yPosition#);
// yError# = sin(correctedYaw# / 57.2958)*(xPositionDesired# - xPosition#) + cos(correctedYaw# / 57.2958)*(yPositionDesired# - yPosition#);
xError# = (xPositionHand - 0.5) - xPosition#;
yError# = (yPositionHand + 0.5) - yPosition#;
controllerSetXYError(&pidCtrl#, xError#, yError#);
controllerCorrectAttitudePID(&pidCtrl#, t.pos[0], t.pos[1], zPosition#, correctedYaw#,
xPositionDesired#, yPositionDesired#, zPositionDesired#,
yawDesired#, &rollControlOutput#, &pitchControlOutput#,
&yawControlOutput#, &thrustControlOutput#);
}
else if(cflieCopter#->m_enumFlightMode == GROUNDED_MODE){
controllerResetAllPID(&pidCtrl#);
rollControlOutput# = 0;
pitchControlOutput# = 0;
yawControlOutput# = 0;
thrustControlOutput# = 0;
}
else{ //Emergency Case (Should never happen)
controllerResetAllPID(&pidCtrl#);
rollControlOutput# = 0;
pitchControlOutput# = 0;
yawControlOutput# = 0;
thrustControlOutput# = 0;
}
#else
controllerCorrectAttitudePID(&pidCtrl#, t.pos[0], t.pos[1], -t.pos[2], correctedYaw#,
xPositionDesired#, yPositionDesired#, zPositionDesired#,
yawDesired#, &rollControlOutput#, &pitchControlOutput#,
&yawControlOutput#, &thrustControlOutput#);
#endif
RunCrazyflie(crRadio(#RADIO NUM), cflieCopter#,
rollControlOutput#, pitchControlOutput#, yawControlOutput#, thrustControlOutput#);
#if USE_LOGGING
#if USE_BASIC_LOGGING
fprintf(out#, "%.6f\t\t", cflieCopter#->currentTime() - initTime# );
fprintf(out#, "%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.6f\t\t%.6f\t\t%.6f\t\t%.6f\t\t%.6f\t\t%.6f\t\t%d\t\t%d",
cflieCopter#->roll(),
cflieCopter#->pitch(),
quadYaw#,
t.pos[0],
t.pos[1],
-t.pos[2],
camYawDeg#,
correctedYaw#,
loopTimeTotal,
loopTimeTotalDelta,
loopTime#,
loopTime#Delta,
vrpnPacketDelta#,
vrpnPacketTime#,
vrpnPacketBackup#,
cflieCopter#->radioRSSI()); //
fprintf(out#, "\n");
#else
fprintf(out#, "%.6f\t\t", cflieCopter#->currentTime() - initTime# );
fprintf(out#, "%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.6f\t\t%.6f\t\t%.6f\t\t%.6f\t\t%.6f\t\t%.6f\t\t%d\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%d\t\t%.3f\t\t%.3f\t\t%.3f\t\t%lu\t\t%lu\t\t%lu\t\t%lu\t\t%.3f\t\t%.3f\t\t%.3f",
cflieCopter#->roll(),
cflieCopter#->pitch(),
quadYaw#,
t.pos[0],
t.pos[1],
-t.pos[2],
camYawDeg#,
correctedYaw#,
loopTimeTotal,
loopTimeTotalDelta,
loopTime#,
loopTime#Delta,
vrpnPacketDelta#,
vrpnPacketTime#,
vrpnPacketBackup#,
xPositionDesired#,
yPositionDesired#,
zPositionDesired#,
yawDesired#,
pitchControlOutput#,
rollControlOutput#,
yawControlOutput#,
thrustControlOutput#,
cflieCopter#->radioRSSI(),
euler[0],
euler[1],
euler[2],
cflieCopter#->motor1(),
cflieCopter#->motor2(),
cflieCopter#->motor3(),
cflieCopter#->motor4(),
cflieCopter#->gyroX(),
cflieCopter#->gyroY(),
cflieCopter#->gyroZ()); //
fprintf(out#, "\n");
#endif
#endif
loopTime#End = cflieCopter#->currentTime() - initTime#;
loopTime# = loopTime#End - loopTime#Start;
} //End Packet Backup If check
else if(vrpnPacketBackup# < 0){ //Failsafe so can't go below 0 (should never happen) | || (vrpnPacketBackup# > 20)?
vrpnPacketBackup# = 0;
// RunCrazyflie(crRadio(#RADIO NUM), cflieCopter#,
// rollControlOutput#, pitchControlOutput#, yawControlOutput#, thrustControlOutput#);
}
else if(vrpnPacketBackup# >= 2){
// cout << "VRPN Packet Backup # Detected: " << vrpnPacketBackup# << endl;
vrpnPacketBackup# --;
// RunCrazyflie(crRadio(#RADIO NUM), cflieCopter#,
// rollControlOutput#, pitchControlOutput#, yawControlOutput#, thrustControlOutput#);
}//End Packet Backup Purge
} //END CALLBACK #
</pre>
</code>
</blockquote>
==Changes in CTRL+C Handler==
----
<center> '''Main Directory''' </center>
<center> [[Crazyflie Swarm|Crazyflie Swarm Home]] | [[PC Client Software]] | [[USB Radio]] | [[Firmware]] | [[FAQ]] </center>
<center> '''Modifications Directory''' </center>
<center> [[Controller]] | [[Logging]] | [[Keyboard Commands]] | [[USB Radio#Changing Radio Channel|Changing Radio Channel]] | [[Flight Modes]] | [[Callbacks]] | [[Adding a Crazyflie]] | [[Firmware]] </center>
632a1af73c5a31f07bd48546458f3b0192b20fef
158
157
2016-07-28T17:57:14Z
Jnoronha
3
/* Changes in CTRL+C Handler */ added changes
wikitext
text/x-wiki
Adding a Crazyflie to the Swarm is simple, but tedious. It's basically just replicating a copy of the other Crazyflies code, but there are multiple files you will need to make changes in. The following list should help you locate all the code you need to replicate:
==Changes in ''vrpn.cpp''==
<blockquote>
<code>
<pre>
vrpn_Tracker_Remote *tracker#;
extern float xPositionDesired#;
extern float yPositionDesired#;
extern float zPositionDesired#;
extern float yawDesired#;
extern float xPosition#;
extern float yPosition#;
extern float zPosition#;
extern CCrazyflie *cflieCopter#;
extern double initTime#;
extern char takeOff#;
extern double takeOffTime#;
void vrpn_init(std::string connectionName, void (*callback)(void*, const vrpn_TRACKERCB),
void (*callback2)(void*, const vrpn_TRACKERCB), void (*callback#)(void*, const vrpn_TRACKERCB), ......, char *key) {
tracker# = new vrpn_Tracker_Remote("Crazyflie2#", connection);
tracker#->register_change_handler(0, callback#);
tracker#->mainloop();
</pre>
</code>
</blockquote>
===Changes in ''nearGround()''===
<blockquote>
<code>
<pre>
void nearGround() //During Landing Mode checks how close to ground quad is for shutdown
{
...
...
...
if(cflieCopter#){
if((cflieCopter#->m_enumFlightMode == LANDING_MODE) && (zPosition# < 0.05))
{
cflieCopter#->m_enumFlightMode = GROUNDED_MODE;
}
}
}
</pre>
</code>
</blockquote>
===Changes in ''updateHand()''===
<blockquote>
<code>
<pre>
void updateHand()
{
if(handMode == 1)
{
// cout << "Hand Roll: " << rollHand << endl;
if(killCount > 5){
...
...
cflieCopter#->m_enumFlightMode = GROUNDED_MODE;
}
else if(trackCount > 5){
...
...
cflieCopter#->m_enumFlightMode = HAND_MODE;
}
else{
...
...
if(zPositionHand > 1.6)
{
...
...
cflieCopter#->m_enumFlightMode = TAKEOFF_MODE;
cout << "Hand Mode: Launching Quads" << endl;
}
else if(zPositionHand < 0.4)
{
...
...
cflieCopter#->m_enumFlightMode = LANDING_MODE;
...
}
}
}
}
</pre>
</code>
</blockquote>
==Changes in ''vrpn.h''==
<blockquote>
<code>
<pre>
void vrpn_init(std::string connectionName, void (*callback)(void*, const vrpn_TRACKERCB),
void (*callback2)(void*, const vrpn_TRACKERCB), void (*callback#)(void*, const vrpn_TRACKERCB), ...., char *key);
</pre>
</code>
</blockquote>
==Changes in ''eris_vrpn.cpp''==
===Global Variables===
<blockquote>
<code>
<pre>
void VRPN_CALLBACK handle_Crazyflie#(void*, const vrpn_TRACKERCB t);
CCrazyRadio *crRadio# = 0; //***NOT NECESSARY IF LESS THAN 3 QUADS PER RADIO***
CCrazyflie *cflieCopter# = 0;
ControllerObject pidCtrl# = { 0 }; // init all fields to zero
float rollControlOutput#;
float pitchControlOutput#;
float yawControlOutput#;
float thrustControlOutput#;
double initTime# = 0;
int vrpnPacketBackup# = 0;
double vrpnBackupTime# = 0;
double vrpnBackupTime#Prev = 0;
double vrpnBackupTime#Delta = 0;
float xPositionDesired# = 0.681;
float yPositionDesired# = 0.129;
float zPositionDesired# = 0.6;
float yawDesired# = -90.0;
float yawDifference# = 0;
float quadYaw# = 0;
float prevQuadYaw# = 0;
float camYawDeg# = 0;
float camYawDeg#Off = 0;
float quadYaw#Off = 0;
float correctedYaw# = 0;
float xError# = 0.0;
float yError# = 0.0;
float xStepPositionError# = 0.0;
float yStepPositionError# = 0.0;
float xPosition# = -0.012;
float yPosition# = -0.008; //Default Crazyflie location setpoints
float zPosition# = 0.75;
char takeOff# = 0;
double loopTime#Start = 0;
double loopTime#End = 0;
double loopTime# = 0;
double loopTime#Prev = 0;
double loopTime#Delta = 0;
double vrpnPacketTime# = 0;
double vrpnPacketTime#Prev = 0;
double vrpnPacketDelta# = 0;
FILE * out# = NULL;
</pre>
</code>
</blockquote>
===Changes in ''main()''===
<blockquote>
<code>
<pre>
controllerResetAllPID( &pidCtrl# );
controllerInit( &pidCtrl# );
vrpn_init("192.168.0.120:3883", handle_pos, handle_Crazyflie2, handle_Crazyflie#, handle_Crazyflie(#+1), ..., &keystroke_now);
cflieCopter# = new CCrazyflie(crRadio(radio dongle number), (Radio Channel));
const char * logHeader# = "#Crazyflie# Log File\n\
#Time\t\t........
if(cflieCopter#)
{
out# = fopen("cflie#.txt", "w");
if(out# == NULL)
{
printf("Could not open cflie#.log:errno %d\n", errno);
exit(-1);
}
fprintf(out#, "%s\n", logHeader#);
}
crRadio#->setARDTime(2000); //Sets Wait Time between Packet Retries (**MUST BE IN INCREMENTS OF 250**)
crRadio#->setARC(0); //Sets Number of times Retries Packet Send
crRadio#->setPower(P_0DBM);
cflieCopter#->setSendSetpoints( true );
initTime# = cflieCopter#->currentTime();
cflieCopter#->m_enumFlightMode = GROUNDED_MODE;
fclose(out#);
delete cflieCopter#;
delete crRadio#;
</pre>
</code>
</blockquote>
==Creating a New Callback==
'''Note:''' To make it easier for this section you can:
#COPY and PASTE the callback code directly after the last callback in the Swarm Client
#Use FIND and REPLACE to replace all '#' signs with the Crazyflie number desired
:*'''IMPORTANT:''' Be careful, some of the '#' symbols are used for the Radio Dongle number also.
<blockquote>
<code>
<pre>
void VRPN_CALLBACK handle_Crazyflie#(void*, const vrpn_TRACKERCB t) {
if(vrpnPacketBackup# < 2) //If VRPN Buffer does NOT have old packets stored up, run main code
{
loopTime#Start = cflieCopter#->currentTime() - initTime#;
loopTime#Delta = loopTime#Start - loopTime#Prev; //Calculates time difference between each loop start
loopTime#Prev = loopTime#Start;
vrpnPacketTime# = t.msg_time.tv_sec + (t.msg_time.tv_usec / 1000000.0);
vrpnPacketDelta# = vrpnPacketTime# - vrpnPacketTime#Prev;
vrpnPacketTime#Prev = vrpnPacketTime#;
vrpnPacketBackup# = ceil(loopTime#Delta/vrpnPacketDelta#); //Calculates estimated # of packets built up in VRPN buffer.
controllerSetAllDt(&pidCtrl#, vrpnPacketDelta#); //Variable dt for controller based on time between packets | vrpnPacketDelta2
cflieCopter1->cheat_process_packets(); //Flush out other Copter Packets
crRadio(#RADIO NUM)->clearPackets();
crRadio(#RADIO NUM)->setChannel( cflieCopter#->radioChannel() );
frameCount++;
// Get the euler angles
q_vec_type euler;
q_to_euler(euler, t.quat);
xPosition# = t.pos[0];
yPosition# = t.pos[1]; //Stores X, Y, and Z Position for use in other Callbacks (external)
zPosition# = -t.pos[2] + 0.05;
#if USE_PRINTOUT
cout << "PID Radio #" << endl << endl;
#endif
#if 0 //UNUSED (old way of storing camera data)
//cout << "\033[2J\033[1;1H"; //Clears Terminal Window to display clean output
cfliePitch = cflieCopter#->pitch();
cflieRoll = cflieCopter#->roll();
cflieYaw = cflieCopter#->yaw();
cflieThrust = cflieCopter#->thrust();
/*
* Position
* x t.pos[0]
* y t.pos[1]
* z t.pos[2]
*
* Orientation
* yaw euler[0] Rotation
* pitch euler[1] East-West movement
* roll euler[2] North-South movement
* Euler's range goes from -pi : +pi
*/
QUAD quad;
quad.vrpnNow = 0;
vrpn_data_t *vrpnData;
vrpnData = (vrpn_data_t*) malloc(sizeof(vrpn_data_t));
vrpnData->usec = t.msg_time.tv_sec + (t.msg_time.tv_usec / 1000000.0);
vrpnData->x = t.pos[0];
vrpnData->y = t.pos[1];
vrpnData->z = -t.pos[2] + 0.05; //Higher Altitude = Negative z //Added Offset for floor below camera system origin
vrpnData->yaw = euler[0];
vrpnData->pitch = euler[1];
vrpnData->roll = euler[2];
xPosition# = t.pos[0];
yPosition# = t.pos[1];
zPosition# = -t.pos[2] + 0.05;
cout << "xPosition of Crazyflie#: " << xPosition# << endl;
quad.vrpnPrev = quad.vrpnNow;
if (quad.vrpnNow == 0) {
quad.vrpnPrev = 0;
quad.vrpnTime0 = vrpnData->usec;
quad.vrpnNow = vrpnData->usec;
} else {
quad.vrpnNow = vrpnData->usec - quad.vrpnTime0;
}
#endif //END UNUSED
//==============YAW CORRECTION========================= (IMPORTANT!!!: YAW CONTROLLER INPUT IS INVERTED IN simple.cpp FILE***)
camYawDeg# = -(euler[0] * 57.2958); //Converts From Radians TO Degrees
quadYaw# = cflieCopter#->yaw();
if (frameCount == 50) {
if (camYawDeg# < 0.0)
camYawDeg#Off = camYawDeg# + 360.0; //Converts from +-180 to full 360 degree form
else
camYawDeg#Off = camYawDeg#;
if(quadYaw# < 0.0)
quadYaw#Off = quadYaw# + 360.0;
else
quadYaw#Off = quadYaw#;
yawDifference# = quadYaw#Off - camYawDeg#Off;
cout << "Yaw# Offset Taken: " << yawDifference# << endl;
}
correctedYaw# = camYawDeg# + yawDifference#;
if(correctedYaw# > 180.0)
correctedYaw# -= 360.0;
else if(correctedYaw# < -180.0)
correctedYaw# += 360.0;
//===============END YAW CORRECTION=========================
#if USE_PRINTOUT
cout << "X: " << t.pos[0] << endl;
cout << "Y: " << t.pos[1] << endl;
cout << "Z: " << -t.pos[2] + 0.05 << endl;
#endif
#if USE_KEYBOARD
if (cflieCopter#->m_enumFlightMode == LANDING_MODE) //Landing Mode (TODO Change to be a keystroke when implemented)
{
//CORRECTS PITCH AND ROLL PID ERRORS TO ACCOUNT FOR QUADS CURRENT YAW DIRECTION
// xError# = cos(correctedYaw# / 57.2958)*(xPositionDesired# - xPosition#) - sin(correctedYaw# / 57.2958)*(yPositionDesired# - yPosition#);
// yError# = sin(correctedYaw# / 57.2958)*(xPositionDesired# - xPosition#) + cos(correctedYaw# / 57.2958)*(yPositionDesired# - yPosition#);
xError# = xPositionDesired# - xPosition#;
yError# = yPositionDesired# - yPosition#;
controllerSetXYError(&pidCtrl#, xError#, yError#);
controllerCorrectAttitudePID(&pidCtrl#, t.pos[0], t.pos[1], zPosition#, correctedYaw#,
xPositionDesired#, yPositionDesired#, -0.4, yawDesired#,
&rollControlOutput#, &pitchControlOutput#, &yawControlOutput#,
&thrustControlOutput#);
takeOff# = 0;
} else if (cflieCopter#->m_enumFlightMode == MIRROR_MODE) { //Acts as Master
xPositionDesired# = -0.012;
yPositionDesired# = -0.200;
zPositionDesired# = 0.75;
if( loopTime#Start - lastTime > 4.0 )
{
toggle = !toggle;
lastTime = loopTime#Start;
}
#if USE_PRINTOUT
cout << "New xPositionDesired: " << xPositionDesired# << endl;
#endif
if(toggle)
{
xStepPositionError# = xPositionDesired# - xPosition#;
yStepPositionError# = yPositionDesired# - yPosition#;
controllerSetXYError(&pidCtrl#, xStepPositionError#, yStepPositionError#);
controllerCorrectAttitudePID(&pidCtrl#, t.pos[0], t.pos[1], zPosition#, correctedYaw#,
xPositionDesired#, yPositionDesired#, zPositionDesired#,
yawDesired#, &rollControlOutput#, &pitchControlOutput#,
&yawControlOutput#, &thrustControlOutput#);
}
else
{
xStepPositionError# = (xPositionDesired# + 0.65) - xPosition#;
yStepPositionError# = (yPositionDesired# + 0.65) - yPosition#;
controllerSetXYError(&pidCtrl#, xStepPositionError#, yStepPositionError#);
controllerCorrectAttitudePID(&pidCtrl#, t.pos[0], t.pos[1], zPosition#, correctedYaw#,
xPositionDesired# + 0.65, yPositionDesired# + 0.65, zPositionDesired#,
yawDesired#, &rollControlOutput#, &pitchControlOutput#,
&yawControlOutput#, &thrustControlOutput#);
//cout << "Toggled!" << endl;
}
} else if (cflieCopter#->m_enumFlightMode == TAKEOFF_MODE) { //correctedYaw#
//CORRECTS PITCH AND ROLL PID ERRORS TO ACCOUNT FOR QUADS CURRENT YAW DIRECTION
// xError# = cos(correctedYaw# / 57.2958)*(xPositionDesired# - xPosition#) - sin(correctedYaw# / 57.2958)*(yPositionDesired# - yPosition#);
// yError# = sin(correctedYaw# / 57.2958)*(xPositionDesired# - xPosition#) + cos(correctedYaw# / 57.2958)*(yPositionDesired# - yPosition#);
xError# = xPositionDesired# - xPosition#;
yError# = yPositionDesired# - yPosition#;
controllerSetXYError(&pidCtrl#, xError#, yError#);
controllerCorrectAttitudePID(&pidCtrl#, t.pos[0], t.pos[1], zPosition#, correctedYaw#,
xPositionDesired#, yPositionDesired#, zPositionDesired#,
yawDesired#, &rollControlOutput#, &pitchControlOutput#,
&yawControlOutput#, &thrustControlOutput#);
}
else if (cflieCopter#->m_enumFlightMode == HAND_MODE) { //correctedYaw#
//CORRECTS PITCH AND ROLL PID ERRORS TO ACCOUNT FOR QUADS CURRENT YAW DIRECTION
// xError# = cos(correctedYaw# / 57.2958)*(xPositionDesired# - xPosition#) - sin(correctedYaw# / 57.2958)*(yPositionDesired# - yPosition#);
// yError# = sin(correctedYaw# / 57.2958)*(xPositionDesired# - xPosition#) + cos(correctedYaw# / 57.2958)*(yPositionDesired# - yPosition#);
xError# = (xPositionHand - 0.5) - xPosition#;
yError# = (yPositionHand + 0.5) - yPosition#;
controllerSetXYError(&pidCtrl#, xError#, yError#);
controllerCorrectAttitudePID(&pidCtrl#, t.pos[0], t.pos[1], zPosition#, correctedYaw#,
xPositionDesired#, yPositionDesired#, zPositionDesired#,
yawDesired#, &rollControlOutput#, &pitchControlOutput#,
&yawControlOutput#, &thrustControlOutput#);
}
else if(cflieCopter#->m_enumFlightMode == GROUNDED_MODE){
controllerResetAllPID(&pidCtrl#);
rollControlOutput# = 0;
pitchControlOutput# = 0;
yawControlOutput# = 0;
thrustControlOutput# = 0;
}
else{ //Emergency Case (Should never happen)
controllerResetAllPID(&pidCtrl#);
rollControlOutput# = 0;
pitchControlOutput# = 0;
yawControlOutput# = 0;
thrustControlOutput# = 0;
}
#else
controllerCorrectAttitudePID(&pidCtrl#, t.pos[0], t.pos[1], -t.pos[2], correctedYaw#,
xPositionDesired#, yPositionDesired#, zPositionDesired#,
yawDesired#, &rollControlOutput#, &pitchControlOutput#,
&yawControlOutput#, &thrustControlOutput#);
#endif
RunCrazyflie(crRadio(#RADIO NUM), cflieCopter#,
rollControlOutput#, pitchControlOutput#, yawControlOutput#, thrustControlOutput#);
#if USE_LOGGING
#if USE_BASIC_LOGGING
fprintf(out#, "%.6f\t\t", cflieCopter#->currentTime() - initTime# );
fprintf(out#, "%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.6f\t\t%.6f\t\t%.6f\t\t%.6f\t\t%.6f\t\t%.6f\t\t%d\t\t%d",
cflieCopter#->roll(),
cflieCopter#->pitch(),
quadYaw#,
t.pos[0],
t.pos[1],
-t.pos[2],
camYawDeg#,
correctedYaw#,
loopTimeTotal,
loopTimeTotalDelta,
loopTime#,
loopTime#Delta,
vrpnPacketDelta#,
vrpnPacketTime#,
vrpnPacketBackup#,
cflieCopter#->radioRSSI()); //
fprintf(out#, "\n");
#else
fprintf(out#, "%.6f\t\t", cflieCopter#->currentTime() - initTime# );
fprintf(out#, "%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.6f\t\t%.6f\t\t%.6f\t\t%.6f\t\t%.6f\t\t%.6f\t\t%d\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%d\t\t%.3f\t\t%.3f\t\t%.3f\t\t%lu\t\t%lu\t\t%lu\t\t%lu\t\t%.3f\t\t%.3f\t\t%.3f",
cflieCopter#->roll(),
cflieCopter#->pitch(),
quadYaw#,
t.pos[0],
t.pos[1],
-t.pos[2],
camYawDeg#,
correctedYaw#,
loopTimeTotal,
loopTimeTotalDelta,
loopTime#,
loopTime#Delta,
vrpnPacketDelta#,
vrpnPacketTime#,
vrpnPacketBackup#,
xPositionDesired#,
yPositionDesired#,
zPositionDesired#,
yawDesired#,
pitchControlOutput#,
rollControlOutput#,
yawControlOutput#,
thrustControlOutput#,
cflieCopter#->radioRSSI(),
euler[0],
euler[1],
euler[2],
cflieCopter#->motor1(),
cflieCopter#->motor2(),
cflieCopter#->motor3(),
cflieCopter#->motor4(),
cflieCopter#->gyroX(),
cflieCopter#->gyroY(),
cflieCopter#->gyroZ()); //
fprintf(out#, "\n");
#endif
#endif
loopTime#End = cflieCopter#->currentTime() - initTime#;
loopTime# = loopTime#End - loopTime#Start;
} //End Packet Backup If check
else if(vrpnPacketBackup# < 0){ //Failsafe so can't go below 0 (should never happen) | || (vrpnPacketBackup# > 20)?
vrpnPacketBackup# = 0;
// RunCrazyflie(crRadio(#RADIO NUM), cflieCopter#,
// rollControlOutput#, pitchControlOutput#, yawControlOutput#, thrustControlOutput#);
}
else if(vrpnPacketBackup# >= 2){
// cout << "VRPN Packet Backup # Detected: " << vrpnPacketBackup# << endl;
vrpnPacketBackup# --;
// RunCrazyflie(crRadio(#RADIO NUM), cflieCopter#,
// rollControlOutput#, pitchControlOutput#, yawControlOutput#, thrustControlOutput#);
}//End Packet Backup Purge
} //END CALLBACK #
</pre>
</code>
</blockquote>
==Changes in CTRL+C Handler==
<blockquote>
<code>
<pre>
cflieCopter#->setThrust(10000);
cout << "Battery#: " << cflieCopter#->batteryLevel() << endl;
cflieCopter#->cycle();
#if USE_LOGGING
...
...
...
fclose(out#);
#endif
delete cflieCopter#;
delete crRadio#;
</pre>
</code>
</blockquote>
----
<center> '''Main Directory''' </center>
<center> [[Crazyflie Swarm|Crazyflie Swarm Home]] | [[PC Client Software]] | [[USB Radio]] | [[Firmware]] | [[FAQ]] </center>
<center> '''Modifications Directory''' </center>
<center> [[Controller]] | [[Logging]] | [[Keyboard Commands]] | [[USB Radio#Changing Radio Channel|Changing Radio Channel]] | [[Flight Modes]] | [[Callbacks]] | [[Adding a Crazyflie]] | [[Firmware]] </center>
4ccbd3921772b66a3a5e66cb5743c774a91740d8
159
158
2016-07-28T17:59:28Z
Jnoronha
3
changed callback and ctrl+c heading levels to be inside of eris_vrpn changes
wikitext
text/x-wiki
Adding a Crazyflie to the Swarm is simple, but tedious. It's basically just replicating a copy of the other Crazyflies code, but there are multiple files you will need to make changes in. The following list should help you locate all the code you need to replicate:
==Changes in ''vrpn.cpp''==
<blockquote>
<code>
<pre>
vrpn_Tracker_Remote *tracker#;
extern float xPositionDesired#;
extern float yPositionDesired#;
extern float zPositionDesired#;
extern float yawDesired#;
extern float xPosition#;
extern float yPosition#;
extern float zPosition#;
extern CCrazyflie *cflieCopter#;
extern double initTime#;
extern char takeOff#;
extern double takeOffTime#;
void vrpn_init(std::string connectionName, void (*callback)(void*, const vrpn_TRACKERCB),
void (*callback2)(void*, const vrpn_TRACKERCB), void (*callback#)(void*, const vrpn_TRACKERCB), ......, char *key) {
tracker# = new vrpn_Tracker_Remote("Crazyflie2#", connection);
tracker#->register_change_handler(0, callback#);
tracker#->mainloop();
</pre>
</code>
</blockquote>
===Changes in ''nearGround()''===
<blockquote>
<code>
<pre>
void nearGround() //During Landing Mode checks how close to ground quad is for shutdown
{
...
...
...
if(cflieCopter#){
if((cflieCopter#->m_enumFlightMode == LANDING_MODE) && (zPosition# < 0.05))
{
cflieCopter#->m_enumFlightMode = GROUNDED_MODE;
}
}
}
</pre>
</code>
</blockquote>
===Changes in ''updateHand()''===
<blockquote>
<code>
<pre>
void updateHand()
{
if(handMode == 1)
{
// cout << "Hand Roll: " << rollHand << endl;
if(killCount > 5){
...
...
cflieCopter#->m_enumFlightMode = GROUNDED_MODE;
}
else if(trackCount > 5){
...
...
cflieCopter#->m_enumFlightMode = HAND_MODE;
}
else{
...
...
if(zPositionHand > 1.6)
{
...
...
cflieCopter#->m_enumFlightMode = TAKEOFF_MODE;
cout << "Hand Mode: Launching Quads" << endl;
}
else if(zPositionHand < 0.4)
{
...
...
cflieCopter#->m_enumFlightMode = LANDING_MODE;
...
}
}
}
}
</pre>
</code>
</blockquote>
==Changes in ''vrpn.h''==
<blockquote>
<code>
<pre>
void vrpn_init(std::string connectionName, void (*callback)(void*, const vrpn_TRACKERCB),
void (*callback2)(void*, const vrpn_TRACKERCB), void (*callback#)(void*, const vrpn_TRACKERCB), ...., char *key);
</pre>
</code>
</blockquote>
==Changes in ''eris_vrpn.cpp''==
===Global Variables===
<blockquote>
<code>
<pre>
void VRPN_CALLBACK handle_Crazyflie#(void*, const vrpn_TRACKERCB t);
CCrazyRadio *crRadio# = 0; //***NOT NECESSARY IF LESS THAN 3 QUADS PER RADIO***
CCrazyflie *cflieCopter# = 0;
ControllerObject pidCtrl# = { 0 }; // init all fields to zero
float rollControlOutput#;
float pitchControlOutput#;
float yawControlOutput#;
float thrustControlOutput#;
double initTime# = 0;
int vrpnPacketBackup# = 0;
double vrpnBackupTime# = 0;
double vrpnBackupTime#Prev = 0;
double vrpnBackupTime#Delta = 0;
float xPositionDesired# = 0.681;
float yPositionDesired# = 0.129;
float zPositionDesired# = 0.6;
float yawDesired# = -90.0;
float yawDifference# = 0;
float quadYaw# = 0;
float prevQuadYaw# = 0;
float camYawDeg# = 0;
float camYawDeg#Off = 0;
float quadYaw#Off = 0;
float correctedYaw# = 0;
float xError# = 0.0;
float yError# = 0.0;
float xStepPositionError# = 0.0;
float yStepPositionError# = 0.0;
float xPosition# = -0.012;
float yPosition# = -0.008; //Default Crazyflie location setpoints
float zPosition# = 0.75;
char takeOff# = 0;
double loopTime#Start = 0;
double loopTime#End = 0;
double loopTime# = 0;
double loopTime#Prev = 0;
double loopTime#Delta = 0;
double vrpnPacketTime# = 0;
double vrpnPacketTime#Prev = 0;
double vrpnPacketDelta# = 0;
FILE * out# = NULL;
</pre>
</code>
</blockquote>
===Changes in ''main()''===
<blockquote>
<code>
<pre>
controllerResetAllPID( &pidCtrl# );
controllerInit( &pidCtrl# );
vrpn_init("192.168.0.120:3883", handle_pos, handle_Crazyflie2, handle_Crazyflie#, handle_Crazyflie(#+1), ..., &keystroke_now);
cflieCopter# = new CCrazyflie(crRadio(radio dongle number), (Radio Channel));
const char * logHeader# = "#Crazyflie# Log File\n\
#Time\t\t........
if(cflieCopter#)
{
out# = fopen("cflie#.txt", "w");
if(out# == NULL)
{
printf("Could not open cflie#.log:errno %d\n", errno);
exit(-1);
}
fprintf(out#, "%s\n", logHeader#);
}
crRadio#->setARDTime(2000); //Sets Wait Time between Packet Retries (**MUST BE IN INCREMENTS OF 250**)
crRadio#->setARC(0); //Sets Number of times Retries Packet Send
crRadio#->setPower(P_0DBM);
cflieCopter#->setSendSetpoints( true );
initTime# = cflieCopter#->currentTime();
cflieCopter#->m_enumFlightMode = GROUNDED_MODE;
fclose(out#);
delete cflieCopter#;
delete crRadio#;
</pre>
</code>
</blockquote>
===Create a New Callback===
'''Note:''' To make it easier for this section you can:
#COPY and PASTE the callback code directly after the last callback in the Swarm Client
#Use FIND and REPLACE to replace all '#' signs with the Crazyflie number desired
:*'''IMPORTANT:''' Be careful, some of the '#' symbols are used for the Radio Dongle number also.
<blockquote>
<code>
<pre>
void VRPN_CALLBACK handle_Crazyflie#(void*, const vrpn_TRACKERCB t) {
if(vrpnPacketBackup# < 2) //If VRPN Buffer does NOT have old packets stored up, run main code
{
loopTime#Start = cflieCopter#->currentTime() - initTime#;
loopTime#Delta = loopTime#Start - loopTime#Prev; //Calculates time difference between each loop start
loopTime#Prev = loopTime#Start;
vrpnPacketTime# = t.msg_time.tv_sec + (t.msg_time.tv_usec / 1000000.0);
vrpnPacketDelta# = vrpnPacketTime# - vrpnPacketTime#Prev;
vrpnPacketTime#Prev = vrpnPacketTime#;
vrpnPacketBackup# = ceil(loopTime#Delta/vrpnPacketDelta#); //Calculates estimated # of packets built up in VRPN buffer.
controllerSetAllDt(&pidCtrl#, vrpnPacketDelta#); //Variable dt for controller based on time between packets | vrpnPacketDelta2
cflieCopter1->cheat_process_packets(); //Flush out other Copter Packets
crRadio(#RADIO NUM)->clearPackets();
crRadio(#RADIO NUM)->setChannel( cflieCopter#->radioChannel() );
frameCount++;
// Get the euler angles
q_vec_type euler;
q_to_euler(euler, t.quat);
xPosition# = t.pos[0];
yPosition# = t.pos[1]; //Stores X, Y, and Z Position for use in other Callbacks (external)
zPosition# = -t.pos[2] + 0.05;
#if USE_PRINTOUT
cout << "PID Radio #" << endl << endl;
#endif
#if 0 //UNUSED (old way of storing camera data)
//cout << "\033[2J\033[1;1H"; //Clears Terminal Window to display clean output
cfliePitch = cflieCopter#->pitch();
cflieRoll = cflieCopter#->roll();
cflieYaw = cflieCopter#->yaw();
cflieThrust = cflieCopter#->thrust();
/*
* Position
* x t.pos[0]
* y t.pos[1]
* z t.pos[2]
*
* Orientation
* yaw euler[0] Rotation
* pitch euler[1] East-West movement
* roll euler[2] North-South movement
* Euler's range goes from -pi : +pi
*/
QUAD quad;
quad.vrpnNow = 0;
vrpn_data_t *vrpnData;
vrpnData = (vrpn_data_t*) malloc(sizeof(vrpn_data_t));
vrpnData->usec = t.msg_time.tv_sec + (t.msg_time.tv_usec / 1000000.0);
vrpnData->x = t.pos[0];
vrpnData->y = t.pos[1];
vrpnData->z = -t.pos[2] + 0.05; //Higher Altitude = Negative z //Added Offset for floor below camera system origin
vrpnData->yaw = euler[0];
vrpnData->pitch = euler[1];
vrpnData->roll = euler[2];
xPosition# = t.pos[0];
yPosition# = t.pos[1];
zPosition# = -t.pos[2] + 0.05;
cout << "xPosition of Crazyflie#: " << xPosition# << endl;
quad.vrpnPrev = quad.vrpnNow;
if (quad.vrpnNow == 0) {
quad.vrpnPrev = 0;
quad.vrpnTime0 = vrpnData->usec;
quad.vrpnNow = vrpnData->usec;
} else {
quad.vrpnNow = vrpnData->usec - quad.vrpnTime0;
}
#endif //END UNUSED
//==============YAW CORRECTION========================= (IMPORTANT!!!: YAW CONTROLLER INPUT IS INVERTED IN simple.cpp FILE***)
camYawDeg# = -(euler[0] * 57.2958); //Converts From Radians TO Degrees
quadYaw# = cflieCopter#->yaw();
if (frameCount == 50) {
if (camYawDeg# < 0.0)
camYawDeg#Off = camYawDeg# + 360.0; //Converts from +-180 to full 360 degree form
else
camYawDeg#Off = camYawDeg#;
if(quadYaw# < 0.0)
quadYaw#Off = quadYaw# + 360.0;
else
quadYaw#Off = quadYaw#;
yawDifference# = quadYaw#Off - camYawDeg#Off;
cout << "Yaw# Offset Taken: " << yawDifference# << endl;
}
correctedYaw# = camYawDeg# + yawDifference#;
if(correctedYaw# > 180.0)
correctedYaw# -= 360.0;
else if(correctedYaw# < -180.0)
correctedYaw# += 360.0;
//===============END YAW CORRECTION=========================
#if USE_PRINTOUT
cout << "X: " << t.pos[0] << endl;
cout << "Y: " << t.pos[1] << endl;
cout << "Z: " << -t.pos[2] + 0.05 << endl;
#endif
#if USE_KEYBOARD
if (cflieCopter#->m_enumFlightMode == LANDING_MODE) //Landing Mode (TODO Change to be a keystroke when implemented)
{
//CORRECTS PITCH AND ROLL PID ERRORS TO ACCOUNT FOR QUADS CURRENT YAW DIRECTION
// xError# = cos(correctedYaw# / 57.2958)*(xPositionDesired# - xPosition#) - sin(correctedYaw# / 57.2958)*(yPositionDesired# - yPosition#);
// yError# = sin(correctedYaw# / 57.2958)*(xPositionDesired# - xPosition#) + cos(correctedYaw# / 57.2958)*(yPositionDesired# - yPosition#);
xError# = xPositionDesired# - xPosition#;
yError# = yPositionDesired# - yPosition#;
controllerSetXYError(&pidCtrl#, xError#, yError#);
controllerCorrectAttitudePID(&pidCtrl#, t.pos[0], t.pos[1], zPosition#, correctedYaw#,
xPositionDesired#, yPositionDesired#, -0.4, yawDesired#,
&rollControlOutput#, &pitchControlOutput#, &yawControlOutput#,
&thrustControlOutput#);
takeOff# = 0;
} else if (cflieCopter#->m_enumFlightMode == MIRROR_MODE) { //Acts as Master
xPositionDesired# = -0.012;
yPositionDesired# = -0.200;
zPositionDesired# = 0.75;
if( loopTime#Start - lastTime > 4.0 )
{
toggle = !toggle;
lastTime = loopTime#Start;
}
#if USE_PRINTOUT
cout << "New xPositionDesired: " << xPositionDesired# << endl;
#endif
if(toggle)
{
xStepPositionError# = xPositionDesired# - xPosition#;
yStepPositionError# = yPositionDesired# - yPosition#;
controllerSetXYError(&pidCtrl#, xStepPositionError#, yStepPositionError#);
controllerCorrectAttitudePID(&pidCtrl#, t.pos[0], t.pos[1], zPosition#, correctedYaw#,
xPositionDesired#, yPositionDesired#, zPositionDesired#,
yawDesired#, &rollControlOutput#, &pitchControlOutput#,
&yawControlOutput#, &thrustControlOutput#);
}
else
{
xStepPositionError# = (xPositionDesired# + 0.65) - xPosition#;
yStepPositionError# = (yPositionDesired# + 0.65) - yPosition#;
controllerSetXYError(&pidCtrl#, xStepPositionError#, yStepPositionError#);
controllerCorrectAttitudePID(&pidCtrl#, t.pos[0], t.pos[1], zPosition#, correctedYaw#,
xPositionDesired# + 0.65, yPositionDesired# + 0.65, zPositionDesired#,
yawDesired#, &rollControlOutput#, &pitchControlOutput#,
&yawControlOutput#, &thrustControlOutput#);
//cout << "Toggled!" << endl;
}
} else if (cflieCopter#->m_enumFlightMode == TAKEOFF_MODE) { //correctedYaw#
//CORRECTS PITCH AND ROLL PID ERRORS TO ACCOUNT FOR QUADS CURRENT YAW DIRECTION
// xError# = cos(correctedYaw# / 57.2958)*(xPositionDesired# - xPosition#) - sin(correctedYaw# / 57.2958)*(yPositionDesired# - yPosition#);
// yError# = sin(correctedYaw# / 57.2958)*(xPositionDesired# - xPosition#) + cos(correctedYaw# / 57.2958)*(yPositionDesired# - yPosition#);
xError# = xPositionDesired# - xPosition#;
yError# = yPositionDesired# - yPosition#;
controllerSetXYError(&pidCtrl#, xError#, yError#);
controllerCorrectAttitudePID(&pidCtrl#, t.pos[0], t.pos[1], zPosition#, correctedYaw#,
xPositionDesired#, yPositionDesired#, zPositionDesired#,
yawDesired#, &rollControlOutput#, &pitchControlOutput#,
&yawControlOutput#, &thrustControlOutput#);
}
else if (cflieCopter#->m_enumFlightMode == HAND_MODE) { //correctedYaw#
//CORRECTS PITCH AND ROLL PID ERRORS TO ACCOUNT FOR QUADS CURRENT YAW DIRECTION
// xError# = cos(correctedYaw# / 57.2958)*(xPositionDesired# - xPosition#) - sin(correctedYaw# / 57.2958)*(yPositionDesired# - yPosition#);
// yError# = sin(correctedYaw# / 57.2958)*(xPositionDesired# - xPosition#) + cos(correctedYaw# / 57.2958)*(yPositionDesired# - yPosition#);
xError# = (xPositionHand - 0.5) - xPosition#;
yError# = (yPositionHand + 0.5) - yPosition#;
controllerSetXYError(&pidCtrl#, xError#, yError#);
controllerCorrectAttitudePID(&pidCtrl#, t.pos[0], t.pos[1], zPosition#, correctedYaw#,
xPositionDesired#, yPositionDesired#, zPositionDesired#,
yawDesired#, &rollControlOutput#, &pitchControlOutput#,
&yawControlOutput#, &thrustControlOutput#);
}
else if(cflieCopter#->m_enumFlightMode == GROUNDED_MODE){
controllerResetAllPID(&pidCtrl#);
rollControlOutput# = 0;
pitchControlOutput# = 0;
yawControlOutput# = 0;
thrustControlOutput# = 0;
}
else{ //Emergency Case (Should never happen)
controllerResetAllPID(&pidCtrl#);
rollControlOutput# = 0;
pitchControlOutput# = 0;
yawControlOutput# = 0;
thrustControlOutput# = 0;
}
#else
controllerCorrectAttitudePID(&pidCtrl#, t.pos[0], t.pos[1], -t.pos[2], correctedYaw#,
xPositionDesired#, yPositionDesired#, zPositionDesired#,
yawDesired#, &rollControlOutput#, &pitchControlOutput#,
&yawControlOutput#, &thrustControlOutput#);
#endif
RunCrazyflie(crRadio(#RADIO NUM), cflieCopter#,
rollControlOutput#, pitchControlOutput#, yawControlOutput#, thrustControlOutput#);
#if USE_LOGGING
#if USE_BASIC_LOGGING
fprintf(out#, "%.6f\t\t", cflieCopter#->currentTime() - initTime# );
fprintf(out#, "%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.6f\t\t%.6f\t\t%.6f\t\t%.6f\t\t%.6f\t\t%.6f\t\t%d\t\t%d",
cflieCopter#->roll(),
cflieCopter#->pitch(),
quadYaw#,
t.pos[0],
t.pos[1],
-t.pos[2],
camYawDeg#,
correctedYaw#,
loopTimeTotal,
loopTimeTotalDelta,
loopTime#,
loopTime#Delta,
vrpnPacketDelta#,
vrpnPacketTime#,
vrpnPacketBackup#,
cflieCopter#->radioRSSI()); //
fprintf(out#, "\n");
#else
fprintf(out#, "%.6f\t\t", cflieCopter#->currentTime() - initTime# );
fprintf(out#, "%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.6f\t\t%.6f\t\t%.6f\t\t%.6f\t\t%.6f\t\t%.6f\t\t%d\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%d\t\t%.3f\t\t%.3f\t\t%.3f\t\t%lu\t\t%lu\t\t%lu\t\t%lu\t\t%.3f\t\t%.3f\t\t%.3f",
cflieCopter#->roll(),
cflieCopter#->pitch(),
quadYaw#,
t.pos[0],
t.pos[1],
-t.pos[2],
camYawDeg#,
correctedYaw#,
loopTimeTotal,
loopTimeTotalDelta,
loopTime#,
loopTime#Delta,
vrpnPacketDelta#,
vrpnPacketTime#,
vrpnPacketBackup#,
xPositionDesired#,
yPositionDesired#,
zPositionDesired#,
yawDesired#,
pitchControlOutput#,
rollControlOutput#,
yawControlOutput#,
thrustControlOutput#,
cflieCopter#->radioRSSI(),
euler[0],
euler[1],
euler[2],
cflieCopter#->motor1(),
cflieCopter#->motor2(),
cflieCopter#->motor3(),
cflieCopter#->motor4(),
cflieCopter#->gyroX(),
cflieCopter#->gyroY(),
cflieCopter#->gyroZ()); //
fprintf(out#, "\n");
#endif
#endif
loopTime#End = cflieCopter#->currentTime() - initTime#;
loopTime# = loopTime#End - loopTime#Start;
} //End Packet Backup If check
else if(vrpnPacketBackup# < 0){ //Failsafe so can't go below 0 (should never happen) | || (vrpnPacketBackup# > 20)?
vrpnPacketBackup# = 0;
// RunCrazyflie(crRadio(#RADIO NUM), cflieCopter#,
// rollControlOutput#, pitchControlOutput#, yawControlOutput#, thrustControlOutput#);
}
else if(vrpnPacketBackup# >= 2){
// cout << "VRPN Packet Backup # Detected: " << vrpnPacketBackup# << endl;
vrpnPacketBackup# --;
// RunCrazyflie(crRadio(#RADIO NUM), cflieCopter#,
// rollControlOutput#, pitchControlOutput#, yawControlOutput#, thrustControlOutput#);
}//End Packet Backup Purge
} //END CALLBACK #
</pre>
</code>
</blockquote>
===Changes in CTRL+C Handler===
<blockquote>
<code>
<pre>
cflieCopter#->setThrust(10000);
cout << "Battery#: " << cflieCopter#->batteryLevel() << endl;
cflieCopter#->cycle();
#if USE_LOGGING
...
...
...
fclose(out#);
#endif
delete cflieCopter#;
delete crRadio#;
</pre>
</code>
</blockquote>
----
<center> '''Main Directory''' </center>
<center> [[Crazyflie Swarm|Crazyflie Swarm Home]] | [[PC Client Software]] | [[USB Radio]] | [[Firmware]] | [[FAQ]] </center>
<center> '''Modifications Directory''' </center>
<center> [[Controller]] | [[Logging]] | [[Keyboard Commands]] | [[USB Radio#Changing Radio Channel|Changing Radio Channel]] | [[Flight Modes]] | [[Callbacks]] | [[Adding a Crazyflie]] | [[Firmware]] </center>
6c39e458cc2693677fa3aae22b96b80eb1b95d58
160
159
2016-07-28T18:00:09Z
Jnoronha
3
punctuation
wikitext
text/x-wiki
Adding a Crazyflie to the Swarm is simple, but tedious. It's basically just replicating a copy of the other Crazyflie's code, but there are multiple files you will need to make changes in. The following list should help you locate all the code you need to replicate:
==Changes in ''vrpn.cpp''==
<blockquote>
<code>
<pre>
vrpn_Tracker_Remote *tracker#;
extern float xPositionDesired#;
extern float yPositionDesired#;
extern float zPositionDesired#;
extern float yawDesired#;
extern float xPosition#;
extern float yPosition#;
extern float zPosition#;
extern CCrazyflie *cflieCopter#;
extern double initTime#;
extern char takeOff#;
extern double takeOffTime#;
void vrpn_init(std::string connectionName, void (*callback)(void*, const vrpn_TRACKERCB),
void (*callback2)(void*, const vrpn_TRACKERCB), void (*callback#)(void*, const vrpn_TRACKERCB), ......, char *key) {
tracker# = new vrpn_Tracker_Remote("Crazyflie2#", connection);
tracker#->register_change_handler(0, callback#);
tracker#->mainloop();
</pre>
</code>
</blockquote>
===Changes in ''nearGround()''===
<blockquote>
<code>
<pre>
void nearGround() //During Landing Mode checks how close to ground quad is for shutdown
{
...
...
...
if(cflieCopter#){
if((cflieCopter#->m_enumFlightMode == LANDING_MODE) && (zPosition# < 0.05))
{
cflieCopter#->m_enumFlightMode = GROUNDED_MODE;
}
}
}
</pre>
</code>
</blockquote>
===Changes in ''updateHand()''===
<blockquote>
<code>
<pre>
void updateHand()
{
if(handMode == 1)
{
// cout << "Hand Roll: " << rollHand << endl;
if(killCount > 5){
...
...
cflieCopter#->m_enumFlightMode = GROUNDED_MODE;
}
else if(trackCount > 5){
...
...
cflieCopter#->m_enumFlightMode = HAND_MODE;
}
else{
...
...
if(zPositionHand > 1.6)
{
...
...
cflieCopter#->m_enumFlightMode = TAKEOFF_MODE;
cout << "Hand Mode: Launching Quads" << endl;
}
else if(zPositionHand < 0.4)
{
...
...
cflieCopter#->m_enumFlightMode = LANDING_MODE;
...
}
}
}
}
</pre>
</code>
</blockquote>
==Changes in ''vrpn.h''==
<blockquote>
<code>
<pre>
void vrpn_init(std::string connectionName, void (*callback)(void*, const vrpn_TRACKERCB),
void (*callback2)(void*, const vrpn_TRACKERCB), void (*callback#)(void*, const vrpn_TRACKERCB), ...., char *key);
</pre>
</code>
</blockquote>
==Changes in ''eris_vrpn.cpp''==
===Global Variables===
<blockquote>
<code>
<pre>
void VRPN_CALLBACK handle_Crazyflie#(void*, const vrpn_TRACKERCB t);
CCrazyRadio *crRadio# = 0; //***NOT NECESSARY IF LESS THAN 3 QUADS PER RADIO***
CCrazyflie *cflieCopter# = 0;
ControllerObject pidCtrl# = { 0 }; // init all fields to zero
float rollControlOutput#;
float pitchControlOutput#;
float yawControlOutput#;
float thrustControlOutput#;
double initTime# = 0;
int vrpnPacketBackup# = 0;
double vrpnBackupTime# = 0;
double vrpnBackupTime#Prev = 0;
double vrpnBackupTime#Delta = 0;
float xPositionDesired# = 0.681;
float yPositionDesired# = 0.129;
float zPositionDesired# = 0.6;
float yawDesired# = -90.0;
float yawDifference# = 0;
float quadYaw# = 0;
float prevQuadYaw# = 0;
float camYawDeg# = 0;
float camYawDeg#Off = 0;
float quadYaw#Off = 0;
float correctedYaw# = 0;
float xError# = 0.0;
float yError# = 0.0;
float xStepPositionError# = 0.0;
float yStepPositionError# = 0.0;
float xPosition# = -0.012;
float yPosition# = -0.008; //Default Crazyflie location setpoints
float zPosition# = 0.75;
char takeOff# = 0;
double loopTime#Start = 0;
double loopTime#End = 0;
double loopTime# = 0;
double loopTime#Prev = 0;
double loopTime#Delta = 0;
double vrpnPacketTime# = 0;
double vrpnPacketTime#Prev = 0;
double vrpnPacketDelta# = 0;
FILE * out# = NULL;
</pre>
</code>
</blockquote>
===Changes in ''main()''===
<blockquote>
<code>
<pre>
controllerResetAllPID( &pidCtrl# );
controllerInit( &pidCtrl# );
vrpn_init("192.168.0.120:3883", handle_pos, handle_Crazyflie2, handle_Crazyflie#, handle_Crazyflie(#+1), ..., &keystroke_now);
cflieCopter# = new CCrazyflie(crRadio(radio dongle number), (Radio Channel));
const char * logHeader# = "#Crazyflie# Log File\n\
#Time\t\t........
if(cflieCopter#)
{
out# = fopen("cflie#.txt", "w");
if(out# == NULL)
{
printf("Could not open cflie#.log:errno %d\n", errno);
exit(-1);
}
fprintf(out#, "%s\n", logHeader#);
}
crRadio#->setARDTime(2000); //Sets Wait Time between Packet Retries (**MUST BE IN INCREMENTS OF 250**)
crRadio#->setARC(0); //Sets Number of times Retries Packet Send
crRadio#->setPower(P_0DBM);
cflieCopter#->setSendSetpoints( true );
initTime# = cflieCopter#->currentTime();
cflieCopter#->m_enumFlightMode = GROUNDED_MODE;
fclose(out#);
delete cflieCopter#;
delete crRadio#;
</pre>
</code>
</blockquote>
===Create a New Callback===
'''Note:''' To make it easier for this section you can:
#COPY and PASTE the callback code directly after the last callback in the Swarm Client
#Use FIND and REPLACE to replace all '#' signs with the Crazyflie number desired
:*'''IMPORTANT:''' Be careful, some of the '#' symbols are used for the Radio Dongle number also.
<blockquote>
<code>
<pre>
void VRPN_CALLBACK handle_Crazyflie#(void*, const vrpn_TRACKERCB t) {
if(vrpnPacketBackup# < 2) //If VRPN Buffer does NOT have old packets stored up, run main code
{
loopTime#Start = cflieCopter#->currentTime() - initTime#;
loopTime#Delta = loopTime#Start - loopTime#Prev; //Calculates time difference between each loop start
loopTime#Prev = loopTime#Start;
vrpnPacketTime# = t.msg_time.tv_sec + (t.msg_time.tv_usec / 1000000.0);
vrpnPacketDelta# = vrpnPacketTime# - vrpnPacketTime#Prev;
vrpnPacketTime#Prev = vrpnPacketTime#;
vrpnPacketBackup# = ceil(loopTime#Delta/vrpnPacketDelta#); //Calculates estimated # of packets built up in VRPN buffer.
controllerSetAllDt(&pidCtrl#, vrpnPacketDelta#); //Variable dt for controller based on time between packets | vrpnPacketDelta2
cflieCopter1->cheat_process_packets(); //Flush out other Copter Packets
crRadio(#RADIO NUM)->clearPackets();
crRadio(#RADIO NUM)->setChannel( cflieCopter#->radioChannel() );
frameCount++;
// Get the euler angles
q_vec_type euler;
q_to_euler(euler, t.quat);
xPosition# = t.pos[0];
yPosition# = t.pos[1]; //Stores X, Y, and Z Position for use in other Callbacks (external)
zPosition# = -t.pos[2] + 0.05;
#if USE_PRINTOUT
cout << "PID Radio #" << endl << endl;
#endif
#if 0 //UNUSED (old way of storing camera data)
//cout << "\033[2J\033[1;1H"; //Clears Terminal Window to display clean output
cfliePitch = cflieCopter#->pitch();
cflieRoll = cflieCopter#->roll();
cflieYaw = cflieCopter#->yaw();
cflieThrust = cflieCopter#->thrust();
/*
* Position
* x t.pos[0]
* y t.pos[1]
* z t.pos[2]
*
* Orientation
* yaw euler[0] Rotation
* pitch euler[1] East-West movement
* roll euler[2] North-South movement
* Euler's range goes from -pi : +pi
*/
QUAD quad;
quad.vrpnNow = 0;
vrpn_data_t *vrpnData;
vrpnData = (vrpn_data_t*) malloc(sizeof(vrpn_data_t));
vrpnData->usec = t.msg_time.tv_sec + (t.msg_time.tv_usec / 1000000.0);
vrpnData->x = t.pos[0];
vrpnData->y = t.pos[1];
vrpnData->z = -t.pos[2] + 0.05; //Higher Altitude = Negative z //Added Offset for floor below camera system origin
vrpnData->yaw = euler[0];
vrpnData->pitch = euler[1];
vrpnData->roll = euler[2];
xPosition# = t.pos[0];
yPosition# = t.pos[1];
zPosition# = -t.pos[2] + 0.05;
cout << "xPosition of Crazyflie#: " << xPosition# << endl;
quad.vrpnPrev = quad.vrpnNow;
if (quad.vrpnNow == 0) {
quad.vrpnPrev = 0;
quad.vrpnTime0 = vrpnData->usec;
quad.vrpnNow = vrpnData->usec;
} else {
quad.vrpnNow = vrpnData->usec - quad.vrpnTime0;
}
#endif //END UNUSED
//==============YAW CORRECTION========================= (IMPORTANT!!!: YAW CONTROLLER INPUT IS INVERTED IN simple.cpp FILE***)
camYawDeg# = -(euler[0] * 57.2958); //Converts From Radians TO Degrees
quadYaw# = cflieCopter#->yaw();
if (frameCount == 50) {
if (camYawDeg# < 0.0)
camYawDeg#Off = camYawDeg# + 360.0; //Converts from +-180 to full 360 degree form
else
camYawDeg#Off = camYawDeg#;
if(quadYaw# < 0.0)
quadYaw#Off = quadYaw# + 360.0;
else
quadYaw#Off = quadYaw#;
yawDifference# = quadYaw#Off - camYawDeg#Off;
cout << "Yaw# Offset Taken: " << yawDifference# << endl;
}
correctedYaw# = camYawDeg# + yawDifference#;
if(correctedYaw# > 180.0)
correctedYaw# -= 360.0;
else if(correctedYaw# < -180.0)
correctedYaw# += 360.0;
//===============END YAW CORRECTION=========================
#if USE_PRINTOUT
cout << "X: " << t.pos[0] << endl;
cout << "Y: " << t.pos[1] << endl;
cout << "Z: " << -t.pos[2] + 0.05 << endl;
#endif
#if USE_KEYBOARD
if (cflieCopter#->m_enumFlightMode == LANDING_MODE) //Landing Mode (TODO Change to be a keystroke when implemented)
{
//CORRECTS PITCH AND ROLL PID ERRORS TO ACCOUNT FOR QUADS CURRENT YAW DIRECTION
// xError# = cos(correctedYaw# / 57.2958)*(xPositionDesired# - xPosition#) - sin(correctedYaw# / 57.2958)*(yPositionDesired# - yPosition#);
// yError# = sin(correctedYaw# / 57.2958)*(xPositionDesired# - xPosition#) + cos(correctedYaw# / 57.2958)*(yPositionDesired# - yPosition#);
xError# = xPositionDesired# - xPosition#;
yError# = yPositionDesired# - yPosition#;
controllerSetXYError(&pidCtrl#, xError#, yError#);
controllerCorrectAttitudePID(&pidCtrl#, t.pos[0], t.pos[1], zPosition#, correctedYaw#,
xPositionDesired#, yPositionDesired#, -0.4, yawDesired#,
&rollControlOutput#, &pitchControlOutput#, &yawControlOutput#,
&thrustControlOutput#);
takeOff# = 0;
} else if (cflieCopter#->m_enumFlightMode == MIRROR_MODE) { //Acts as Master
xPositionDesired# = -0.012;
yPositionDesired# = -0.200;
zPositionDesired# = 0.75;
if( loopTime#Start - lastTime > 4.0 )
{
toggle = !toggle;
lastTime = loopTime#Start;
}
#if USE_PRINTOUT
cout << "New xPositionDesired: " << xPositionDesired# << endl;
#endif
if(toggle)
{
xStepPositionError# = xPositionDesired# - xPosition#;
yStepPositionError# = yPositionDesired# - yPosition#;
controllerSetXYError(&pidCtrl#, xStepPositionError#, yStepPositionError#);
controllerCorrectAttitudePID(&pidCtrl#, t.pos[0], t.pos[1], zPosition#, correctedYaw#,
xPositionDesired#, yPositionDesired#, zPositionDesired#,
yawDesired#, &rollControlOutput#, &pitchControlOutput#,
&yawControlOutput#, &thrustControlOutput#);
}
else
{
xStepPositionError# = (xPositionDesired# + 0.65) - xPosition#;
yStepPositionError# = (yPositionDesired# + 0.65) - yPosition#;
controllerSetXYError(&pidCtrl#, xStepPositionError#, yStepPositionError#);
controllerCorrectAttitudePID(&pidCtrl#, t.pos[0], t.pos[1], zPosition#, correctedYaw#,
xPositionDesired# + 0.65, yPositionDesired# + 0.65, zPositionDesired#,
yawDesired#, &rollControlOutput#, &pitchControlOutput#,
&yawControlOutput#, &thrustControlOutput#);
//cout << "Toggled!" << endl;
}
} else if (cflieCopter#->m_enumFlightMode == TAKEOFF_MODE) { //correctedYaw#
//CORRECTS PITCH AND ROLL PID ERRORS TO ACCOUNT FOR QUADS CURRENT YAW DIRECTION
// xError# = cos(correctedYaw# / 57.2958)*(xPositionDesired# - xPosition#) - sin(correctedYaw# / 57.2958)*(yPositionDesired# - yPosition#);
// yError# = sin(correctedYaw# / 57.2958)*(xPositionDesired# - xPosition#) + cos(correctedYaw# / 57.2958)*(yPositionDesired# - yPosition#);
xError# = xPositionDesired# - xPosition#;
yError# = yPositionDesired# - yPosition#;
controllerSetXYError(&pidCtrl#, xError#, yError#);
controllerCorrectAttitudePID(&pidCtrl#, t.pos[0], t.pos[1], zPosition#, correctedYaw#,
xPositionDesired#, yPositionDesired#, zPositionDesired#,
yawDesired#, &rollControlOutput#, &pitchControlOutput#,
&yawControlOutput#, &thrustControlOutput#);
}
else if (cflieCopter#->m_enumFlightMode == HAND_MODE) { //correctedYaw#
//CORRECTS PITCH AND ROLL PID ERRORS TO ACCOUNT FOR QUADS CURRENT YAW DIRECTION
// xError# = cos(correctedYaw# / 57.2958)*(xPositionDesired# - xPosition#) - sin(correctedYaw# / 57.2958)*(yPositionDesired# - yPosition#);
// yError# = sin(correctedYaw# / 57.2958)*(xPositionDesired# - xPosition#) + cos(correctedYaw# / 57.2958)*(yPositionDesired# - yPosition#);
xError# = (xPositionHand - 0.5) - xPosition#;
yError# = (yPositionHand + 0.5) - yPosition#;
controllerSetXYError(&pidCtrl#, xError#, yError#);
controllerCorrectAttitudePID(&pidCtrl#, t.pos[0], t.pos[1], zPosition#, correctedYaw#,
xPositionDesired#, yPositionDesired#, zPositionDesired#,
yawDesired#, &rollControlOutput#, &pitchControlOutput#,
&yawControlOutput#, &thrustControlOutput#);
}
else if(cflieCopter#->m_enumFlightMode == GROUNDED_MODE){
controllerResetAllPID(&pidCtrl#);
rollControlOutput# = 0;
pitchControlOutput# = 0;
yawControlOutput# = 0;
thrustControlOutput# = 0;
}
else{ //Emergency Case (Should never happen)
controllerResetAllPID(&pidCtrl#);
rollControlOutput# = 0;
pitchControlOutput# = 0;
yawControlOutput# = 0;
thrustControlOutput# = 0;
}
#else
controllerCorrectAttitudePID(&pidCtrl#, t.pos[0], t.pos[1], -t.pos[2], correctedYaw#,
xPositionDesired#, yPositionDesired#, zPositionDesired#,
yawDesired#, &rollControlOutput#, &pitchControlOutput#,
&yawControlOutput#, &thrustControlOutput#);
#endif
RunCrazyflie(crRadio(#RADIO NUM), cflieCopter#,
rollControlOutput#, pitchControlOutput#, yawControlOutput#, thrustControlOutput#);
#if USE_LOGGING
#if USE_BASIC_LOGGING
fprintf(out#, "%.6f\t\t", cflieCopter#->currentTime() - initTime# );
fprintf(out#, "%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.6f\t\t%.6f\t\t%.6f\t\t%.6f\t\t%.6f\t\t%.6f\t\t%d\t\t%d",
cflieCopter#->roll(),
cflieCopter#->pitch(),
quadYaw#,
t.pos[0],
t.pos[1],
-t.pos[2],
camYawDeg#,
correctedYaw#,
loopTimeTotal,
loopTimeTotalDelta,
loopTime#,
loopTime#Delta,
vrpnPacketDelta#,
vrpnPacketTime#,
vrpnPacketBackup#,
cflieCopter#->radioRSSI()); //
fprintf(out#, "\n");
#else
fprintf(out#, "%.6f\t\t", cflieCopter#->currentTime() - initTime# );
fprintf(out#, "%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.6f\t\t%.6f\t\t%.6f\t\t%.6f\t\t%.6f\t\t%.6f\t\t%d\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%d\t\t%.3f\t\t%.3f\t\t%.3f\t\t%lu\t\t%lu\t\t%lu\t\t%lu\t\t%.3f\t\t%.3f\t\t%.3f",
cflieCopter#->roll(),
cflieCopter#->pitch(),
quadYaw#,
t.pos[0],
t.pos[1],
-t.pos[2],
camYawDeg#,
correctedYaw#,
loopTimeTotal,
loopTimeTotalDelta,
loopTime#,
loopTime#Delta,
vrpnPacketDelta#,
vrpnPacketTime#,
vrpnPacketBackup#,
xPositionDesired#,
yPositionDesired#,
zPositionDesired#,
yawDesired#,
pitchControlOutput#,
rollControlOutput#,
yawControlOutput#,
thrustControlOutput#,
cflieCopter#->radioRSSI(),
euler[0],
euler[1],
euler[2],
cflieCopter#->motor1(),
cflieCopter#->motor2(),
cflieCopter#->motor3(),
cflieCopter#->motor4(),
cflieCopter#->gyroX(),
cflieCopter#->gyroY(),
cflieCopter#->gyroZ()); //
fprintf(out#, "\n");
#endif
#endif
loopTime#End = cflieCopter#->currentTime() - initTime#;
loopTime# = loopTime#End - loopTime#Start;
} //End Packet Backup If check
else if(vrpnPacketBackup# < 0){ //Failsafe so can't go below 0 (should never happen) | || (vrpnPacketBackup# > 20)?
vrpnPacketBackup# = 0;
// RunCrazyflie(crRadio(#RADIO NUM), cflieCopter#,
// rollControlOutput#, pitchControlOutput#, yawControlOutput#, thrustControlOutput#);
}
else if(vrpnPacketBackup# >= 2){
// cout << "VRPN Packet Backup # Detected: " << vrpnPacketBackup# << endl;
vrpnPacketBackup# --;
// RunCrazyflie(crRadio(#RADIO NUM), cflieCopter#,
// rollControlOutput#, pitchControlOutput#, yawControlOutput#, thrustControlOutput#);
}//End Packet Backup Purge
} //END CALLBACK #
</pre>
</code>
</blockquote>
===Changes in CTRL+C Handler===
<blockquote>
<code>
<pre>
cflieCopter#->setThrust(10000);
cout << "Battery#: " << cflieCopter#->batteryLevel() << endl;
cflieCopter#->cycle();
#if USE_LOGGING
...
...
...
fclose(out#);
#endif
delete cflieCopter#;
delete crRadio#;
</pre>
</code>
</blockquote>
----
<center> '''Main Directory''' </center>
<center> [[Crazyflie Swarm|Crazyflie Swarm Home]] | [[PC Client Software]] | [[USB Radio]] | [[Firmware]] | [[FAQ]] </center>
<center> '''Modifications Directory''' </center>
<center> [[Controller]] | [[Logging]] | [[Keyboard Commands]] | [[USB Radio#Changing Radio Channel|Changing Radio Channel]] | [[Flight Modes]] | [[Callbacks]] | [[Adding a Crazyflie]] | [[Firmware]] </center>
3fc528735308a83a3b5af1b6c777404234ce75b0
161
160
2016-07-28T18:04:51Z
Jnoronha
3
added a note about the '#' symbol
wikitext
text/x-wiki
Adding a Crazyflie to the Swarm is simple, but tedious. It's basically just replicating a copy of the other Crazyflie's code, but there are multiple files you will need to make changes in. The following list should help you locate all the code you need to replicate:
*'''Note:''' Most of these changes will have a '#' symbol, you '''need to replace it''' with the corresponding Crazyflie number you are adding.
==Changes in ''vrpn.cpp''==
<blockquote>
<code>
<pre>
vrpn_Tracker_Remote *tracker#;
extern float xPositionDesired#;
extern float yPositionDesired#;
extern float zPositionDesired#;
extern float yawDesired#;
extern float xPosition#;
extern float yPosition#;
extern float zPosition#;
extern CCrazyflie *cflieCopter#;
extern double initTime#;
extern char takeOff#;
extern double takeOffTime#;
void vrpn_init(std::string connectionName, void (*callback)(void*, const vrpn_TRACKERCB),
void (*callback2)(void*, const vrpn_TRACKERCB), void (*callback#)(void*, const vrpn_TRACKERCB), ......, char *key) {
tracker# = new vrpn_Tracker_Remote("Crazyflie2#", connection);
tracker#->register_change_handler(0, callback#);
tracker#->mainloop();
</pre>
</code>
</blockquote>
===Changes in ''nearGround()''===
<blockquote>
<code>
<pre>
void nearGround() //During Landing Mode checks how close to ground quad is for shutdown
{
...
...
...
if(cflieCopter#){
if((cflieCopter#->m_enumFlightMode == LANDING_MODE) && (zPosition# < 0.05))
{
cflieCopter#->m_enumFlightMode = GROUNDED_MODE;
}
}
}
</pre>
</code>
</blockquote>
===Changes in ''updateHand()''===
<blockquote>
<code>
<pre>
void updateHand()
{
if(handMode == 1)
{
// cout << "Hand Roll: " << rollHand << endl;
if(killCount > 5){
...
...
cflieCopter#->m_enumFlightMode = GROUNDED_MODE;
}
else if(trackCount > 5){
...
...
cflieCopter#->m_enumFlightMode = HAND_MODE;
}
else{
...
...
if(zPositionHand > 1.6)
{
...
...
cflieCopter#->m_enumFlightMode = TAKEOFF_MODE;
cout << "Hand Mode: Launching Quads" << endl;
}
else if(zPositionHand < 0.4)
{
...
...
cflieCopter#->m_enumFlightMode = LANDING_MODE;
...
}
}
}
}
</pre>
</code>
</blockquote>
==Changes in ''vrpn.h''==
<blockquote>
<code>
<pre>
void vrpn_init(std::string connectionName, void (*callback)(void*, const vrpn_TRACKERCB),
void (*callback2)(void*, const vrpn_TRACKERCB), void (*callback#)(void*, const vrpn_TRACKERCB), ...., char *key);
</pre>
</code>
</blockquote>
==Changes in ''eris_vrpn.cpp''==
===Global Variables===
<blockquote>
<code>
<pre>
void VRPN_CALLBACK handle_Crazyflie#(void*, const vrpn_TRACKERCB t);
CCrazyRadio *crRadio# = 0; //***NOT NECESSARY IF LESS THAN 3 QUADS PER RADIO***
CCrazyflie *cflieCopter# = 0;
ControllerObject pidCtrl# = { 0 }; // init all fields to zero
float rollControlOutput#;
float pitchControlOutput#;
float yawControlOutput#;
float thrustControlOutput#;
double initTime# = 0;
int vrpnPacketBackup# = 0;
double vrpnBackupTime# = 0;
double vrpnBackupTime#Prev = 0;
double vrpnBackupTime#Delta = 0;
float xPositionDesired# = 0.681;
float yPositionDesired# = 0.129;
float zPositionDesired# = 0.6;
float yawDesired# = -90.0;
float yawDifference# = 0;
float quadYaw# = 0;
float prevQuadYaw# = 0;
float camYawDeg# = 0;
float camYawDeg#Off = 0;
float quadYaw#Off = 0;
float correctedYaw# = 0;
float xError# = 0.0;
float yError# = 0.0;
float xStepPositionError# = 0.0;
float yStepPositionError# = 0.0;
float xPosition# = -0.012;
float yPosition# = -0.008; //Default Crazyflie location setpoints
float zPosition# = 0.75;
char takeOff# = 0;
double loopTime#Start = 0;
double loopTime#End = 0;
double loopTime# = 0;
double loopTime#Prev = 0;
double loopTime#Delta = 0;
double vrpnPacketTime# = 0;
double vrpnPacketTime#Prev = 0;
double vrpnPacketDelta# = 0;
FILE * out# = NULL;
</pre>
</code>
</blockquote>
===Changes in ''main()''===
<blockquote>
<code>
<pre>
controllerResetAllPID( &pidCtrl# );
controllerInit( &pidCtrl# );
vrpn_init("192.168.0.120:3883", handle_pos, handle_Crazyflie2, handle_Crazyflie#, handle_Crazyflie(#+1), ..., &keystroke_now);
cflieCopter# = new CCrazyflie(crRadio(radio dongle number), (Radio Channel));
const char * logHeader# = "#Crazyflie# Log File\n\
#Time\t\t........
if(cflieCopter#)
{
out# = fopen("cflie#.txt", "w");
if(out# == NULL)
{
printf("Could not open cflie#.log:errno %d\n", errno);
exit(-1);
}
fprintf(out#, "%s\n", logHeader#);
}
crRadio#->setARDTime(2000); //Sets Wait Time between Packet Retries (**MUST BE IN INCREMENTS OF 250**)
crRadio#->setARC(0); //Sets Number of times Retries Packet Send
crRadio#->setPower(P_0DBM);
cflieCopter#->setSendSetpoints( true );
initTime# = cflieCopter#->currentTime();
cflieCopter#->m_enumFlightMode = GROUNDED_MODE;
fclose(out#);
delete cflieCopter#;
delete crRadio#;
</pre>
</code>
</blockquote>
===Create a New Callback===
'''Note:''' To make it easier for this section you can:
#COPY and PASTE the callback code directly after the last callback in the Swarm Client
#Use FIND and REPLACE to replace all '#' signs with the Crazyflie number desired
:*'''IMPORTANT:''' Be careful, some of the '#' symbols are used for the Radio Dongle number also.
<blockquote>
<code>
<pre>
void VRPN_CALLBACK handle_Crazyflie#(void*, const vrpn_TRACKERCB t) {
if(vrpnPacketBackup# < 2) //If VRPN Buffer does NOT have old packets stored up, run main code
{
loopTime#Start = cflieCopter#->currentTime() - initTime#;
loopTime#Delta = loopTime#Start - loopTime#Prev; //Calculates time difference between each loop start
loopTime#Prev = loopTime#Start;
vrpnPacketTime# = t.msg_time.tv_sec + (t.msg_time.tv_usec / 1000000.0);
vrpnPacketDelta# = vrpnPacketTime# - vrpnPacketTime#Prev;
vrpnPacketTime#Prev = vrpnPacketTime#;
vrpnPacketBackup# = ceil(loopTime#Delta/vrpnPacketDelta#); //Calculates estimated # of packets built up in VRPN buffer.
controllerSetAllDt(&pidCtrl#, vrpnPacketDelta#); //Variable dt for controller based on time between packets | vrpnPacketDelta2
cflieCopter1->cheat_process_packets(); //Flush out other Copter Packets
crRadio(#RADIO NUM)->clearPackets();
crRadio(#RADIO NUM)->setChannel( cflieCopter#->radioChannel() );
frameCount++;
// Get the euler angles
q_vec_type euler;
q_to_euler(euler, t.quat);
xPosition# = t.pos[0];
yPosition# = t.pos[1]; //Stores X, Y, and Z Position for use in other Callbacks (external)
zPosition# = -t.pos[2] + 0.05;
#if USE_PRINTOUT
cout << "PID Radio #" << endl << endl;
#endif
#if 0 //UNUSED (old way of storing camera data)
//cout << "\033[2J\033[1;1H"; //Clears Terminal Window to display clean output
cfliePitch = cflieCopter#->pitch();
cflieRoll = cflieCopter#->roll();
cflieYaw = cflieCopter#->yaw();
cflieThrust = cflieCopter#->thrust();
/*
* Position
* x t.pos[0]
* y t.pos[1]
* z t.pos[2]
*
* Orientation
* yaw euler[0] Rotation
* pitch euler[1] East-West movement
* roll euler[2] North-South movement
* Euler's range goes from -pi : +pi
*/
QUAD quad;
quad.vrpnNow = 0;
vrpn_data_t *vrpnData;
vrpnData = (vrpn_data_t*) malloc(sizeof(vrpn_data_t));
vrpnData->usec = t.msg_time.tv_sec + (t.msg_time.tv_usec / 1000000.0);
vrpnData->x = t.pos[0];
vrpnData->y = t.pos[1];
vrpnData->z = -t.pos[2] + 0.05; //Higher Altitude = Negative z //Added Offset for floor below camera system origin
vrpnData->yaw = euler[0];
vrpnData->pitch = euler[1];
vrpnData->roll = euler[2];
xPosition# = t.pos[0];
yPosition# = t.pos[1];
zPosition# = -t.pos[2] + 0.05;
cout << "xPosition of Crazyflie#: " << xPosition# << endl;
quad.vrpnPrev = quad.vrpnNow;
if (quad.vrpnNow == 0) {
quad.vrpnPrev = 0;
quad.vrpnTime0 = vrpnData->usec;
quad.vrpnNow = vrpnData->usec;
} else {
quad.vrpnNow = vrpnData->usec - quad.vrpnTime0;
}
#endif //END UNUSED
//==============YAW CORRECTION========================= (IMPORTANT!!!: YAW CONTROLLER INPUT IS INVERTED IN simple.cpp FILE***)
camYawDeg# = -(euler[0] * 57.2958); //Converts From Radians TO Degrees
quadYaw# = cflieCopter#->yaw();
if (frameCount == 50) {
if (camYawDeg# < 0.0)
camYawDeg#Off = camYawDeg# + 360.0; //Converts from +-180 to full 360 degree form
else
camYawDeg#Off = camYawDeg#;
if(quadYaw# < 0.0)
quadYaw#Off = quadYaw# + 360.0;
else
quadYaw#Off = quadYaw#;
yawDifference# = quadYaw#Off - camYawDeg#Off;
cout << "Yaw# Offset Taken: " << yawDifference# << endl;
}
correctedYaw# = camYawDeg# + yawDifference#;
if(correctedYaw# > 180.0)
correctedYaw# -= 360.0;
else if(correctedYaw# < -180.0)
correctedYaw# += 360.0;
//===============END YAW CORRECTION=========================
#if USE_PRINTOUT
cout << "X: " << t.pos[0] << endl;
cout << "Y: " << t.pos[1] << endl;
cout << "Z: " << -t.pos[2] + 0.05 << endl;
#endif
#if USE_KEYBOARD
if (cflieCopter#->m_enumFlightMode == LANDING_MODE) //Landing Mode (TODO Change to be a keystroke when implemented)
{
//CORRECTS PITCH AND ROLL PID ERRORS TO ACCOUNT FOR QUADS CURRENT YAW DIRECTION
// xError# = cos(correctedYaw# / 57.2958)*(xPositionDesired# - xPosition#) - sin(correctedYaw# / 57.2958)*(yPositionDesired# - yPosition#);
// yError# = sin(correctedYaw# / 57.2958)*(xPositionDesired# - xPosition#) + cos(correctedYaw# / 57.2958)*(yPositionDesired# - yPosition#);
xError# = xPositionDesired# - xPosition#;
yError# = yPositionDesired# - yPosition#;
controllerSetXYError(&pidCtrl#, xError#, yError#);
controllerCorrectAttitudePID(&pidCtrl#, t.pos[0], t.pos[1], zPosition#, correctedYaw#,
xPositionDesired#, yPositionDesired#, -0.4, yawDesired#,
&rollControlOutput#, &pitchControlOutput#, &yawControlOutput#,
&thrustControlOutput#);
takeOff# = 0;
} else if (cflieCopter#->m_enumFlightMode == MIRROR_MODE) { //Acts as Master
xPositionDesired# = -0.012;
yPositionDesired# = -0.200;
zPositionDesired# = 0.75;
if( loopTime#Start - lastTime > 4.0 )
{
toggle = !toggle;
lastTime = loopTime#Start;
}
#if USE_PRINTOUT
cout << "New xPositionDesired: " << xPositionDesired# << endl;
#endif
if(toggle)
{
xStepPositionError# = xPositionDesired# - xPosition#;
yStepPositionError# = yPositionDesired# - yPosition#;
controllerSetXYError(&pidCtrl#, xStepPositionError#, yStepPositionError#);
controllerCorrectAttitudePID(&pidCtrl#, t.pos[0], t.pos[1], zPosition#, correctedYaw#,
xPositionDesired#, yPositionDesired#, zPositionDesired#,
yawDesired#, &rollControlOutput#, &pitchControlOutput#,
&yawControlOutput#, &thrustControlOutput#);
}
else
{
xStepPositionError# = (xPositionDesired# + 0.65) - xPosition#;
yStepPositionError# = (yPositionDesired# + 0.65) - yPosition#;
controllerSetXYError(&pidCtrl#, xStepPositionError#, yStepPositionError#);
controllerCorrectAttitudePID(&pidCtrl#, t.pos[0], t.pos[1], zPosition#, correctedYaw#,
xPositionDesired# + 0.65, yPositionDesired# + 0.65, zPositionDesired#,
yawDesired#, &rollControlOutput#, &pitchControlOutput#,
&yawControlOutput#, &thrustControlOutput#);
//cout << "Toggled!" << endl;
}
} else if (cflieCopter#->m_enumFlightMode == TAKEOFF_MODE) { //correctedYaw#
//CORRECTS PITCH AND ROLL PID ERRORS TO ACCOUNT FOR QUADS CURRENT YAW DIRECTION
// xError# = cos(correctedYaw# / 57.2958)*(xPositionDesired# - xPosition#) - sin(correctedYaw# / 57.2958)*(yPositionDesired# - yPosition#);
// yError# = sin(correctedYaw# / 57.2958)*(xPositionDesired# - xPosition#) + cos(correctedYaw# / 57.2958)*(yPositionDesired# - yPosition#);
xError# = xPositionDesired# - xPosition#;
yError# = yPositionDesired# - yPosition#;
controllerSetXYError(&pidCtrl#, xError#, yError#);
controllerCorrectAttitudePID(&pidCtrl#, t.pos[0], t.pos[1], zPosition#, correctedYaw#,
xPositionDesired#, yPositionDesired#, zPositionDesired#,
yawDesired#, &rollControlOutput#, &pitchControlOutput#,
&yawControlOutput#, &thrustControlOutput#);
}
else if (cflieCopter#->m_enumFlightMode == HAND_MODE) { //correctedYaw#
//CORRECTS PITCH AND ROLL PID ERRORS TO ACCOUNT FOR QUADS CURRENT YAW DIRECTION
// xError# = cos(correctedYaw# / 57.2958)*(xPositionDesired# - xPosition#) - sin(correctedYaw# / 57.2958)*(yPositionDesired# - yPosition#);
// yError# = sin(correctedYaw# / 57.2958)*(xPositionDesired# - xPosition#) + cos(correctedYaw# / 57.2958)*(yPositionDesired# - yPosition#);
xError# = (xPositionHand - 0.5) - xPosition#;
yError# = (yPositionHand + 0.5) - yPosition#;
controllerSetXYError(&pidCtrl#, xError#, yError#);
controllerCorrectAttitudePID(&pidCtrl#, t.pos[0], t.pos[1], zPosition#, correctedYaw#,
xPositionDesired#, yPositionDesired#, zPositionDesired#,
yawDesired#, &rollControlOutput#, &pitchControlOutput#,
&yawControlOutput#, &thrustControlOutput#);
}
else if(cflieCopter#->m_enumFlightMode == GROUNDED_MODE){
controllerResetAllPID(&pidCtrl#);
rollControlOutput# = 0;
pitchControlOutput# = 0;
yawControlOutput# = 0;
thrustControlOutput# = 0;
}
else{ //Emergency Case (Should never happen)
controllerResetAllPID(&pidCtrl#);
rollControlOutput# = 0;
pitchControlOutput# = 0;
yawControlOutput# = 0;
thrustControlOutput# = 0;
}
#else
controllerCorrectAttitudePID(&pidCtrl#, t.pos[0], t.pos[1], -t.pos[2], correctedYaw#,
xPositionDesired#, yPositionDesired#, zPositionDesired#,
yawDesired#, &rollControlOutput#, &pitchControlOutput#,
&yawControlOutput#, &thrustControlOutput#);
#endif
RunCrazyflie(crRadio(#RADIO NUM), cflieCopter#,
rollControlOutput#, pitchControlOutput#, yawControlOutput#, thrustControlOutput#);
#if USE_LOGGING
#if USE_BASIC_LOGGING
fprintf(out#, "%.6f\t\t", cflieCopter#->currentTime() - initTime# );
fprintf(out#, "%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.6f\t\t%.6f\t\t%.6f\t\t%.6f\t\t%.6f\t\t%.6f\t\t%d\t\t%d",
cflieCopter#->roll(),
cflieCopter#->pitch(),
quadYaw#,
t.pos[0],
t.pos[1],
-t.pos[2],
camYawDeg#,
correctedYaw#,
loopTimeTotal,
loopTimeTotalDelta,
loopTime#,
loopTime#Delta,
vrpnPacketDelta#,
vrpnPacketTime#,
vrpnPacketBackup#,
cflieCopter#->radioRSSI()); //
fprintf(out#, "\n");
#else
fprintf(out#, "%.6f\t\t", cflieCopter#->currentTime() - initTime# );
fprintf(out#, "%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.6f\t\t%.6f\t\t%.6f\t\t%.6f\t\t%.6f\t\t%.6f\t\t%d\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%d\t\t%.3f\t\t%.3f\t\t%.3f\t\t%lu\t\t%lu\t\t%lu\t\t%lu\t\t%.3f\t\t%.3f\t\t%.3f",
cflieCopter#->roll(),
cflieCopter#->pitch(),
quadYaw#,
t.pos[0],
t.pos[1],
-t.pos[2],
camYawDeg#,
correctedYaw#,
loopTimeTotal,
loopTimeTotalDelta,
loopTime#,
loopTime#Delta,
vrpnPacketDelta#,
vrpnPacketTime#,
vrpnPacketBackup#,
xPositionDesired#,
yPositionDesired#,
zPositionDesired#,
yawDesired#,
pitchControlOutput#,
rollControlOutput#,
yawControlOutput#,
thrustControlOutput#,
cflieCopter#->radioRSSI(),
euler[0],
euler[1],
euler[2],
cflieCopter#->motor1(),
cflieCopter#->motor2(),
cflieCopter#->motor3(),
cflieCopter#->motor4(),
cflieCopter#->gyroX(),
cflieCopter#->gyroY(),
cflieCopter#->gyroZ()); //
fprintf(out#, "\n");
#endif
#endif
loopTime#End = cflieCopter#->currentTime() - initTime#;
loopTime# = loopTime#End - loopTime#Start;
} //End Packet Backup If check
else if(vrpnPacketBackup# < 0){ //Failsafe so can't go below 0 (should never happen) | || (vrpnPacketBackup# > 20)?
vrpnPacketBackup# = 0;
// RunCrazyflie(crRadio(#RADIO NUM), cflieCopter#,
// rollControlOutput#, pitchControlOutput#, yawControlOutput#, thrustControlOutput#);
}
else if(vrpnPacketBackup# >= 2){
// cout << "VRPN Packet Backup # Detected: " << vrpnPacketBackup# << endl;
vrpnPacketBackup# --;
// RunCrazyflie(crRadio(#RADIO NUM), cflieCopter#,
// rollControlOutput#, pitchControlOutput#, yawControlOutput#, thrustControlOutput#);
}//End Packet Backup Purge
} //END CALLBACK #
</pre>
</code>
</blockquote>
===Changes in CTRL+C Handler===
<blockquote>
<code>
<pre>
cflieCopter#->setThrust(10000);
cout << "Battery#: " << cflieCopter#->batteryLevel() << endl;
cflieCopter#->cycle();
#if USE_LOGGING
...
...
...
fclose(out#);
#endif
delete cflieCopter#;
delete crRadio#;
</pre>
</code>
</blockquote>
----
<center> '''Main Directory''' </center>
<center> [[Crazyflie Swarm|Crazyflie Swarm Home]] | [[PC Client Software]] | [[USB Radio]] | [[Firmware]] | [[FAQ]] </center>
<center> '''Modifications Directory''' </center>
<center> [[Controller]] | [[Logging]] | [[Keyboard Commands]] | [[USB Radio#Changing Radio Channel|Changing Radio Channel]] | [[Flight Modes]] | [[Callbacks]] | [[Adding a Crazyflie]] | [[Firmware]] </center>
e2f05b96aff0320be04dce91aedf0af5c68175f0
162
161
2016-07-28T18:05:09Z
Jnoronha
3
bolded more
wikitext
text/x-wiki
Adding a Crazyflie to the Swarm is simple, but tedious. It's basically just replicating a copy of the other Crazyflie's code, but there are multiple files you will need to make changes in. The following list should help you locate all the code you need to replicate:
*'''Note:''' Most of these changes will have a '#' symbol, you '''need to replace it with the corresponding Crazyflie number''' you are adding.
==Changes in ''vrpn.cpp''==
<blockquote>
<code>
<pre>
vrpn_Tracker_Remote *tracker#;
extern float xPositionDesired#;
extern float yPositionDesired#;
extern float zPositionDesired#;
extern float yawDesired#;
extern float xPosition#;
extern float yPosition#;
extern float zPosition#;
extern CCrazyflie *cflieCopter#;
extern double initTime#;
extern char takeOff#;
extern double takeOffTime#;
void vrpn_init(std::string connectionName, void (*callback)(void*, const vrpn_TRACKERCB),
void (*callback2)(void*, const vrpn_TRACKERCB), void (*callback#)(void*, const vrpn_TRACKERCB), ......, char *key) {
tracker# = new vrpn_Tracker_Remote("Crazyflie2#", connection);
tracker#->register_change_handler(0, callback#);
tracker#->mainloop();
</pre>
</code>
</blockquote>
===Changes in ''nearGround()''===
<blockquote>
<code>
<pre>
void nearGround() //During Landing Mode checks how close to ground quad is for shutdown
{
...
...
...
if(cflieCopter#){
if((cflieCopter#->m_enumFlightMode == LANDING_MODE) && (zPosition# < 0.05))
{
cflieCopter#->m_enumFlightMode = GROUNDED_MODE;
}
}
}
</pre>
</code>
</blockquote>
===Changes in ''updateHand()''===
<blockquote>
<code>
<pre>
void updateHand()
{
if(handMode == 1)
{
// cout << "Hand Roll: " << rollHand << endl;
if(killCount > 5){
...
...
cflieCopter#->m_enumFlightMode = GROUNDED_MODE;
}
else if(trackCount > 5){
...
...
cflieCopter#->m_enumFlightMode = HAND_MODE;
}
else{
...
...
if(zPositionHand > 1.6)
{
...
...
cflieCopter#->m_enumFlightMode = TAKEOFF_MODE;
cout << "Hand Mode: Launching Quads" << endl;
}
else if(zPositionHand < 0.4)
{
...
...
cflieCopter#->m_enumFlightMode = LANDING_MODE;
...
}
}
}
}
</pre>
</code>
</blockquote>
==Changes in ''vrpn.h''==
<blockquote>
<code>
<pre>
void vrpn_init(std::string connectionName, void (*callback)(void*, const vrpn_TRACKERCB),
void (*callback2)(void*, const vrpn_TRACKERCB), void (*callback#)(void*, const vrpn_TRACKERCB), ...., char *key);
</pre>
</code>
</blockquote>
==Changes in ''eris_vrpn.cpp''==
===Global Variables===
<blockquote>
<code>
<pre>
void VRPN_CALLBACK handle_Crazyflie#(void*, const vrpn_TRACKERCB t);
CCrazyRadio *crRadio# = 0; //***NOT NECESSARY IF LESS THAN 3 QUADS PER RADIO***
CCrazyflie *cflieCopter# = 0;
ControllerObject pidCtrl# = { 0 }; // init all fields to zero
float rollControlOutput#;
float pitchControlOutput#;
float yawControlOutput#;
float thrustControlOutput#;
double initTime# = 0;
int vrpnPacketBackup# = 0;
double vrpnBackupTime# = 0;
double vrpnBackupTime#Prev = 0;
double vrpnBackupTime#Delta = 0;
float xPositionDesired# = 0.681;
float yPositionDesired# = 0.129;
float zPositionDesired# = 0.6;
float yawDesired# = -90.0;
float yawDifference# = 0;
float quadYaw# = 0;
float prevQuadYaw# = 0;
float camYawDeg# = 0;
float camYawDeg#Off = 0;
float quadYaw#Off = 0;
float correctedYaw# = 0;
float xError# = 0.0;
float yError# = 0.0;
float xStepPositionError# = 0.0;
float yStepPositionError# = 0.0;
float xPosition# = -0.012;
float yPosition# = -0.008; //Default Crazyflie location setpoints
float zPosition# = 0.75;
char takeOff# = 0;
double loopTime#Start = 0;
double loopTime#End = 0;
double loopTime# = 0;
double loopTime#Prev = 0;
double loopTime#Delta = 0;
double vrpnPacketTime# = 0;
double vrpnPacketTime#Prev = 0;
double vrpnPacketDelta# = 0;
FILE * out# = NULL;
</pre>
</code>
</blockquote>
===Changes in ''main()''===
<blockquote>
<code>
<pre>
controllerResetAllPID( &pidCtrl# );
controllerInit( &pidCtrl# );
vrpn_init("192.168.0.120:3883", handle_pos, handle_Crazyflie2, handle_Crazyflie#, handle_Crazyflie(#+1), ..., &keystroke_now);
cflieCopter# = new CCrazyflie(crRadio(radio dongle number), (Radio Channel));
const char * logHeader# = "#Crazyflie# Log File\n\
#Time\t\t........
if(cflieCopter#)
{
out# = fopen("cflie#.txt", "w");
if(out# == NULL)
{
printf("Could not open cflie#.log:errno %d\n", errno);
exit(-1);
}
fprintf(out#, "%s\n", logHeader#);
}
crRadio#->setARDTime(2000); //Sets Wait Time between Packet Retries (**MUST BE IN INCREMENTS OF 250**)
crRadio#->setARC(0); //Sets Number of times Retries Packet Send
crRadio#->setPower(P_0DBM);
cflieCopter#->setSendSetpoints( true );
initTime# = cflieCopter#->currentTime();
cflieCopter#->m_enumFlightMode = GROUNDED_MODE;
fclose(out#);
delete cflieCopter#;
delete crRadio#;
</pre>
</code>
</blockquote>
===Create a New Callback===
'''Note:''' To make it easier for this section you can:
#COPY and PASTE the callback code directly after the last callback in the Swarm Client
#Use FIND and REPLACE to replace all '#' signs with the Crazyflie number desired
:*'''IMPORTANT:''' Be careful, some of the '#' symbols are used for the Radio Dongle number also.
<blockquote>
<code>
<pre>
void VRPN_CALLBACK handle_Crazyflie#(void*, const vrpn_TRACKERCB t) {
if(vrpnPacketBackup# < 2) //If VRPN Buffer does NOT have old packets stored up, run main code
{
loopTime#Start = cflieCopter#->currentTime() - initTime#;
loopTime#Delta = loopTime#Start - loopTime#Prev; //Calculates time difference between each loop start
loopTime#Prev = loopTime#Start;
vrpnPacketTime# = t.msg_time.tv_sec + (t.msg_time.tv_usec / 1000000.0);
vrpnPacketDelta# = vrpnPacketTime# - vrpnPacketTime#Prev;
vrpnPacketTime#Prev = vrpnPacketTime#;
vrpnPacketBackup# = ceil(loopTime#Delta/vrpnPacketDelta#); //Calculates estimated # of packets built up in VRPN buffer.
controllerSetAllDt(&pidCtrl#, vrpnPacketDelta#); //Variable dt for controller based on time between packets | vrpnPacketDelta2
cflieCopter1->cheat_process_packets(); //Flush out other Copter Packets
crRadio(#RADIO NUM)->clearPackets();
crRadio(#RADIO NUM)->setChannel( cflieCopter#->radioChannel() );
frameCount++;
// Get the euler angles
q_vec_type euler;
q_to_euler(euler, t.quat);
xPosition# = t.pos[0];
yPosition# = t.pos[1]; //Stores X, Y, and Z Position for use in other Callbacks (external)
zPosition# = -t.pos[2] + 0.05;
#if USE_PRINTOUT
cout << "PID Radio #" << endl << endl;
#endif
#if 0 //UNUSED (old way of storing camera data)
//cout << "\033[2J\033[1;1H"; //Clears Terminal Window to display clean output
cfliePitch = cflieCopter#->pitch();
cflieRoll = cflieCopter#->roll();
cflieYaw = cflieCopter#->yaw();
cflieThrust = cflieCopter#->thrust();
/*
* Position
* x t.pos[0]
* y t.pos[1]
* z t.pos[2]
*
* Orientation
* yaw euler[0] Rotation
* pitch euler[1] East-West movement
* roll euler[2] North-South movement
* Euler's range goes from -pi : +pi
*/
QUAD quad;
quad.vrpnNow = 0;
vrpn_data_t *vrpnData;
vrpnData = (vrpn_data_t*) malloc(sizeof(vrpn_data_t));
vrpnData->usec = t.msg_time.tv_sec + (t.msg_time.tv_usec / 1000000.0);
vrpnData->x = t.pos[0];
vrpnData->y = t.pos[1];
vrpnData->z = -t.pos[2] + 0.05; //Higher Altitude = Negative z //Added Offset for floor below camera system origin
vrpnData->yaw = euler[0];
vrpnData->pitch = euler[1];
vrpnData->roll = euler[2];
xPosition# = t.pos[0];
yPosition# = t.pos[1];
zPosition# = -t.pos[2] + 0.05;
cout << "xPosition of Crazyflie#: " << xPosition# << endl;
quad.vrpnPrev = quad.vrpnNow;
if (quad.vrpnNow == 0) {
quad.vrpnPrev = 0;
quad.vrpnTime0 = vrpnData->usec;
quad.vrpnNow = vrpnData->usec;
} else {
quad.vrpnNow = vrpnData->usec - quad.vrpnTime0;
}
#endif //END UNUSED
//==============YAW CORRECTION========================= (IMPORTANT!!!: YAW CONTROLLER INPUT IS INVERTED IN simple.cpp FILE***)
camYawDeg# = -(euler[0] * 57.2958); //Converts From Radians TO Degrees
quadYaw# = cflieCopter#->yaw();
if (frameCount == 50) {
if (camYawDeg# < 0.0)
camYawDeg#Off = camYawDeg# + 360.0; //Converts from +-180 to full 360 degree form
else
camYawDeg#Off = camYawDeg#;
if(quadYaw# < 0.0)
quadYaw#Off = quadYaw# + 360.0;
else
quadYaw#Off = quadYaw#;
yawDifference# = quadYaw#Off - camYawDeg#Off;
cout << "Yaw# Offset Taken: " << yawDifference# << endl;
}
correctedYaw# = camYawDeg# + yawDifference#;
if(correctedYaw# > 180.0)
correctedYaw# -= 360.0;
else if(correctedYaw# < -180.0)
correctedYaw# += 360.0;
//===============END YAW CORRECTION=========================
#if USE_PRINTOUT
cout << "X: " << t.pos[0] << endl;
cout << "Y: " << t.pos[1] << endl;
cout << "Z: " << -t.pos[2] + 0.05 << endl;
#endif
#if USE_KEYBOARD
if (cflieCopter#->m_enumFlightMode == LANDING_MODE) //Landing Mode (TODO Change to be a keystroke when implemented)
{
//CORRECTS PITCH AND ROLL PID ERRORS TO ACCOUNT FOR QUADS CURRENT YAW DIRECTION
// xError# = cos(correctedYaw# / 57.2958)*(xPositionDesired# - xPosition#) - sin(correctedYaw# / 57.2958)*(yPositionDesired# - yPosition#);
// yError# = sin(correctedYaw# / 57.2958)*(xPositionDesired# - xPosition#) + cos(correctedYaw# / 57.2958)*(yPositionDesired# - yPosition#);
xError# = xPositionDesired# - xPosition#;
yError# = yPositionDesired# - yPosition#;
controllerSetXYError(&pidCtrl#, xError#, yError#);
controllerCorrectAttitudePID(&pidCtrl#, t.pos[0], t.pos[1], zPosition#, correctedYaw#,
xPositionDesired#, yPositionDesired#, -0.4, yawDesired#,
&rollControlOutput#, &pitchControlOutput#, &yawControlOutput#,
&thrustControlOutput#);
takeOff# = 0;
} else if (cflieCopter#->m_enumFlightMode == MIRROR_MODE) { //Acts as Master
xPositionDesired# = -0.012;
yPositionDesired# = -0.200;
zPositionDesired# = 0.75;
if( loopTime#Start - lastTime > 4.0 )
{
toggle = !toggle;
lastTime = loopTime#Start;
}
#if USE_PRINTOUT
cout << "New xPositionDesired: " << xPositionDesired# << endl;
#endif
if(toggle)
{
xStepPositionError# = xPositionDesired# - xPosition#;
yStepPositionError# = yPositionDesired# - yPosition#;
controllerSetXYError(&pidCtrl#, xStepPositionError#, yStepPositionError#);
controllerCorrectAttitudePID(&pidCtrl#, t.pos[0], t.pos[1], zPosition#, correctedYaw#,
xPositionDesired#, yPositionDesired#, zPositionDesired#,
yawDesired#, &rollControlOutput#, &pitchControlOutput#,
&yawControlOutput#, &thrustControlOutput#);
}
else
{
xStepPositionError# = (xPositionDesired# + 0.65) - xPosition#;
yStepPositionError# = (yPositionDesired# + 0.65) - yPosition#;
controllerSetXYError(&pidCtrl#, xStepPositionError#, yStepPositionError#);
controllerCorrectAttitudePID(&pidCtrl#, t.pos[0], t.pos[1], zPosition#, correctedYaw#,
xPositionDesired# + 0.65, yPositionDesired# + 0.65, zPositionDesired#,
yawDesired#, &rollControlOutput#, &pitchControlOutput#,
&yawControlOutput#, &thrustControlOutput#);
//cout << "Toggled!" << endl;
}
} else if (cflieCopter#->m_enumFlightMode == TAKEOFF_MODE) { //correctedYaw#
//CORRECTS PITCH AND ROLL PID ERRORS TO ACCOUNT FOR QUADS CURRENT YAW DIRECTION
// xError# = cos(correctedYaw# / 57.2958)*(xPositionDesired# - xPosition#) - sin(correctedYaw# / 57.2958)*(yPositionDesired# - yPosition#);
// yError# = sin(correctedYaw# / 57.2958)*(xPositionDesired# - xPosition#) + cos(correctedYaw# / 57.2958)*(yPositionDesired# - yPosition#);
xError# = xPositionDesired# - xPosition#;
yError# = yPositionDesired# - yPosition#;
controllerSetXYError(&pidCtrl#, xError#, yError#);
controllerCorrectAttitudePID(&pidCtrl#, t.pos[0], t.pos[1], zPosition#, correctedYaw#,
xPositionDesired#, yPositionDesired#, zPositionDesired#,
yawDesired#, &rollControlOutput#, &pitchControlOutput#,
&yawControlOutput#, &thrustControlOutput#);
}
else if (cflieCopter#->m_enumFlightMode == HAND_MODE) { //correctedYaw#
//CORRECTS PITCH AND ROLL PID ERRORS TO ACCOUNT FOR QUADS CURRENT YAW DIRECTION
// xError# = cos(correctedYaw# / 57.2958)*(xPositionDesired# - xPosition#) - sin(correctedYaw# / 57.2958)*(yPositionDesired# - yPosition#);
// yError# = sin(correctedYaw# / 57.2958)*(xPositionDesired# - xPosition#) + cos(correctedYaw# / 57.2958)*(yPositionDesired# - yPosition#);
xError# = (xPositionHand - 0.5) - xPosition#;
yError# = (yPositionHand + 0.5) - yPosition#;
controllerSetXYError(&pidCtrl#, xError#, yError#);
controllerCorrectAttitudePID(&pidCtrl#, t.pos[0], t.pos[1], zPosition#, correctedYaw#,
xPositionDesired#, yPositionDesired#, zPositionDesired#,
yawDesired#, &rollControlOutput#, &pitchControlOutput#,
&yawControlOutput#, &thrustControlOutput#);
}
else if(cflieCopter#->m_enumFlightMode == GROUNDED_MODE){
controllerResetAllPID(&pidCtrl#);
rollControlOutput# = 0;
pitchControlOutput# = 0;
yawControlOutput# = 0;
thrustControlOutput# = 0;
}
else{ //Emergency Case (Should never happen)
controllerResetAllPID(&pidCtrl#);
rollControlOutput# = 0;
pitchControlOutput# = 0;
yawControlOutput# = 0;
thrustControlOutput# = 0;
}
#else
controllerCorrectAttitudePID(&pidCtrl#, t.pos[0], t.pos[1], -t.pos[2], correctedYaw#,
xPositionDesired#, yPositionDesired#, zPositionDesired#,
yawDesired#, &rollControlOutput#, &pitchControlOutput#,
&yawControlOutput#, &thrustControlOutput#);
#endif
RunCrazyflie(crRadio(#RADIO NUM), cflieCopter#,
rollControlOutput#, pitchControlOutput#, yawControlOutput#, thrustControlOutput#);
#if USE_LOGGING
#if USE_BASIC_LOGGING
fprintf(out#, "%.6f\t\t", cflieCopter#->currentTime() - initTime# );
fprintf(out#, "%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.6f\t\t%.6f\t\t%.6f\t\t%.6f\t\t%.6f\t\t%.6f\t\t%d\t\t%d",
cflieCopter#->roll(),
cflieCopter#->pitch(),
quadYaw#,
t.pos[0],
t.pos[1],
-t.pos[2],
camYawDeg#,
correctedYaw#,
loopTimeTotal,
loopTimeTotalDelta,
loopTime#,
loopTime#Delta,
vrpnPacketDelta#,
vrpnPacketTime#,
vrpnPacketBackup#,
cflieCopter#->radioRSSI()); //
fprintf(out#, "\n");
#else
fprintf(out#, "%.6f\t\t", cflieCopter#->currentTime() - initTime# );
fprintf(out#, "%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.6f\t\t%.6f\t\t%.6f\t\t%.6f\t\t%.6f\t\t%.6f\t\t%d\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%d\t\t%.3f\t\t%.3f\t\t%.3f\t\t%lu\t\t%lu\t\t%lu\t\t%lu\t\t%.3f\t\t%.3f\t\t%.3f",
cflieCopter#->roll(),
cflieCopter#->pitch(),
quadYaw#,
t.pos[0],
t.pos[1],
-t.pos[2],
camYawDeg#,
correctedYaw#,
loopTimeTotal,
loopTimeTotalDelta,
loopTime#,
loopTime#Delta,
vrpnPacketDelta#,
vrpnPacketTime#,
vrpnPacketBackup#,
xPositionDesired#,
yPositionDesired#,
zPositionDesired#,
yawDesired#,
pitchControlOutput#,
rollControlOutput#,
yawControlOutput#,
thrustControlOutput#,
cflieCopter#->radioRSSI(),
euler[0],
euler[1],
euler[2],
cflieCopter#->motor1(),
cflieCopter#->motor2(),
cflieCopter#->motor3(),
cflieCopter#->motor4(),
cflieCopter#->gyroX(),
cflieCopter#->gyroY(),
cflieCopter#->gyroZ()); //
fprintf(out#, "\n");
#endif
#endif
loopTime#End = cflieCopter#->currentTime() - initTime#;
loopTime# = loopTime#End - loopTime#Start;
} //End Packet Backup If check
else if(vrpnPacketBackup# < 0){ //Failsafe so can't go below 0 (should never happen) | || (vrpnPacketBackup# > 20)?
vrpnPacketBackup# = 0;
// RunCrazyflie(crRadio(#RADIO NUM), cflieCopter#,
// rollControlOutput#, pitchControlOutput#, yawControlOutput#, thrustControlOutput#);
}
else if(vrpnPacketBackup# >= 2){
// cout << "VRPN Packet Backup # Detected: " << vrpnPacketBackup# << endl;
vrpnPacketBackup# --;
// RunCrazyflie(crRadio(#RADIO NUM), cflieCopter#,
// rollControlOutput#, pitchControlOutput#, yawControlOutput#, thrustControlOutput#);
}//End Packet Backup Purge
} //END CALLBACK #
</pre>
</code>
</blockquote>
===Changes in CTRL+C Handler===
<blockquote>
<code>
<pre>
cflieCopter#->setThrust(10000);
cout << "Battery#: " << cflieCopter#->batteryLevel() << endl;
cflieCopter#->cycle();
#if USE_LOGGING
...
...
...
fclose(out#);
#endif
delete cflieCopter#;
delete crRadio#;
</pre>
</code>
</blockquote>
----
<center> '''Main Directory''' </center>
<center> [[Crazyflie Swarm|Crazyflie Swarm Home]] | [[PC Client Software]] | [[USB Radio]] | [[Firmware]] | [[FAQ]] </center>
<center> '''Modifications Directory''' </center>
<center> [[Controller]] | [[Logging]] | [[Keyboard Commands]] | [[USB Radio#Changing Radio Channel|Changing Radio Channel]] | [[Flight Modes]] | [[Callbacks]] | [[Adding a Crazyflie]] | [[Firmware]] </center>
58ae3b3c28a725bc7465b379de4d526adc856264
PC Client Software
0
25
163
134
2016-07-28T18:24:14Z
Jnoronha
3
/* Makefile */ added the makefile code
wikitext
text/x-wiki
The PC Client software comes in many forms. The out-of-the-box Client is written in Python and has a Graphical User Interface (GUI). The GUI is well suited for beginners, but can only support a single Radio and a single Crazyflie at a time. The easiest way to start out is with the [https://wiki.bitcraze.io/projects:virtualmachine:index Bitcraze Virtual Machine (VM)], which comes with all the files and dependencies pre-installed and can run on any computer (Windows, Mac, Linux, etc.).
For more advanced users who want to use the swarm capabilities of our platform will have to use the [[#Swarm Client|Swarm Client]] we developed in C and C++.
==[https://wiki.bitcraze.io/projects:virtualmachine:index Bitcraze VM]==
('''Note:''' The VM is updated frequently so the information below may be different than the current VM)
The Bitcraze wiki has a tutorial on [https://wiki.bitcraze.io/projects:virtualmachine:tutorials:vmware-win7 installing the VM]. Along with another tutorial on how to get started [https://www.bitcraze.io/getting-started-with-development/ using the VM].
These are both very simple starting guides that will help you become familiar with the VM.
===Crazyflie Client GUI===
On the VM you can find the Crazyflie Client Graphical User Interface (GUI). To run the Client you want to open a terminal and navigate to <code>projects/''''FIND PATH''''</code> and then run the command <code>sudo ./bin/cfclient</code>
(Alternatively, you can use the desktop to navigate to the folder and open a terminal there)
Once you do that you should see something similar to this:
[[Image:DefaultCrazyflieGUIMainScreen.JPG|500px]]
This is the main screen of the Client GUI and there are many tabs and features that you can access directly from this screen.
The most important parts of this screen are the following:
#Connect Button
#Bootloader (Crazyflie Drop Down -> Bootloader)
#Plotter Tab
#Log Blocks Tab
#Parameters Tab
====Connect Button====
This is where you will scan for Crazyflies that are powered ON. All Crazyflies not already connected will show up in the popup
[[Image:DefaultCrazyflieGUIConnectScreen.JPG|400px]]
We get a return that says <code>radio://0/45/2M</code>, this line is the identifier string of the Crazyflie we are trying to connect to.
What this is saying is that we got a return from a Radio (Radio 0 specifically), from a Crazyflie on Channel 45 using a data rate of 2Mbps.
====Bootloader====
This where you can install new Firmware to the Crazyflie.
[[Image:DefaultCrazyflieGUIBootloader.JPG|500px]]
The first thing you'll need to update is to build the Firmware version you want into a .bin file. You can do this by just running the <code>make</code> command in terminal while located inside the Firmware directory you have modified.
Once you have that .bin file built you:
#Open the bootloader shown
#Hold down the power button on the Crazyflie 2.0 for around 3 seconds until the 2 blue LED's flash and alternate. This puts the Crazyflie in bootloader mode. ('''NOTE:''' Recommend having '''ALL other Crazyflies OFF''' or else it could accidentally flash both Crazyflies.)
#Then hit ''Initiate bootloader cold boot'' (it should connect to the Crazyflie in bootloader mode after a few seconds, Status will change from 'Not Connected' to 'Connected')
#Hit ''Browse'' and find the .bin file you built earlier.
#Then click ''Program'' and wait for the progress bar to complete.
#Restart the Crazyflie in Firmware mode and make sure it starts up normally, if something seems wrong just repeat steps 2 through 6 again.
====Logging Tab====
Once you connect to a Crazyflie you can monitor certain log variables that have been set up. You will see a plot of the data similar to this:
[[Image:DefaultCrazyflieGUILoggerScreen.JPG|400px]]
On this screen we can do the following things:
*Dropdown Menu at the top of the screen
**Select which log block you want to plot on screen.
*Scale the X-axis of the plot by:
**Range
**Number of Samples
**Time in Seconds
**Manually
*Scale the Y-axis by:
**Automatically
**Manual Range
====Parameters Tab====
This tab displays all the parameters currently set up on the Crazyflie Firmware. Once you connect to a Crazyflie it lists these parameters in a table format similar to below:
[[Image:DefaultCrazyflieGUIParametersScreen.JPG|400px]]
For each parameter we get its Name, Variable Type, Access Type (Read/Write), and its Current Value.
We can also modify the parameter values on this screen in real-time and the changes will be sent to the Crazyflie automatically.
('''Note:''' Any parameter changes made on this screen are NOT preserved when you turn OFF the Crazyflie.)
==Swarm Client==
The swarm Client is a re-creation of the Original Client but programmed in C and C++.
The benefit of this is that
*We use a unified language between Client and Firmware
*Easily migrate this platform to any linux distribution that can install the Crazyflie dependencies.
**Our platform code itself requires only the VRPN libraries and a generic C compiler.
===Using the Swarm Client===
The Swarm Client uses the terminal interface for User Input.
[[Image:CrazyflieTerminalInitial.png|400px]]
Here we see what the initial Terminal looks like before we do anything.
:1. The first thing you want to do before any testing is to run the <code>sudo make</code> command in the Swarm Client directory. (Yes, the 'sudo' is necessary)
::This will make sure you have all the necessary dependencies, that the code is error free, and then it will build an executable (.exe) file of the Swarm Client code. An error free make will look something like this:
::[[Image:CrazyflieTerminalPostMake.png|400px]]
::There will be warnings, but those don't cause any issues right now.
:2. Pre-Test Checklist
::*Camera System is Turned on and Crazyflie Trackables are opened and visible.
::*Radios are plugged into the USB Ports on the Client computer.
::*Crazyflies are ON and NOT in an Error State.
:3. Run the executable file using the command <code>sudo ./eris_vrpn</code> in the same directory (Yes, the 'sudo' is necessary). This will start the program initialization and a bunch of status info will flood the screen. You will know the program is ready for input when you see the following:
::[[Image:CrazyflieTerminalProgramStarted.png|400px]]
::This means that the Crazyflie yaw has been synchronized with the Camera system and they are ready to fly.
:4. Input a Keyboard Command
::This will depend on what you have programmed as the keyboard input commands. As of 7/19/16 we have the following Keyboard Commands active:
::*'1' - Rotates Yaw of Crazyflie1 +45 degrees
::*'2' - Rotates Yaw of Crazyflie1 -45 degrees
::*'q' - Ends Main Loop (OBSOLETE - Replaced with ctrl + c)
::*'e' - Landing Mode (for ALL Crazyflies)
::*'t' - Crazyflie1 Take-Off
::*'y' - Crazyflie2 Take-Off
::*'u' - Crazyflie3 Take-Off
::*'i' - Crazyflie4 Take-Off
::*'h' - Hand Gesture Mode (for ALL Crazyflies)
::*'m' - Mirror Mode (for ALL Crazyflies)
::*ctrl+c - Quits Program, performs all cleanup.
::An example of what this would look like in the Terminal is shown here:
::[[Image:CrazyflieTerminalKeyboardInput.png|400px]]
::So you can see we commanded all 4 Crazyflies to take off (t,y,u,i), then activated Landing Mode (e), then activated Hand Mode (h), and then Ended the Program (ctrl+c).
:5. End Program when finished (ctrl+c)
::This will end the program loop, print the current battery levels, and Delete the Radio pointers (shown at the end of the previous figure)
===Makefile===
The Swarm Client is compiled by a simple makefile. So when you call ''sudo make'' this makefile converts the C++ code files into an executable (.exe) for us.
<blockquote>
<code>
<pre>
g++ = g++ -Wall
all: eris_vrpn
eris_vrpn: eris_vrpn.h eris_vrpn.cpp vrpn.h vrpn.cpp CCrazyflie.h CCrazyflie.cpp
CCrazyRadio.h CCrazyRadio.cpp CCRTPPacket.h CCRTPPacket.cpp CTOC.h CTOC.cpp
simple.cpp simple.h pid.h pid.c controller.h controller.c multicast.c
$(g++) -g -O0 -o eris_vrpn eris_vrpn.cpp vrpn.cpp CCrazyflie.cpp
CCrazyRadio.cpp CCRTPPacket.cpp CTOC.cpp simple.cpp pid.c controller.c
multicast.c -lquat -lvrpn -lpthread -lusb-1.0
clean:
rm -f *.o eris_vrpn
</pre>
</code>
</blockquote>
----
<center> '''Main Directory''' </center>
<center> [[Crazyflie Swarm|Crazyflie Swarm Home]] | [[PC Client Software]] | [[USB Radio]] | [[Firmware]] | [[FAQ]] </center>
<center> '''Modifications Directory''' </center>
<center> [[Controller]] | [[Logging]] | [[Keyboard Commands]] | [[USB Radio#Changing Radio Channel|Changing Radio Channel]] | [[Flight Modes]] | [[Callbacks]] | [[Adding a Crazyflie]] | [[Firmware]] </center>
4f0c282502b293018efc0e3e4e78f41e84d3cfc2
Future Project Ideas
0
47
164
2016-07-28T18:55:42Z
Jnoronha
3
added PID to firmware details
wikitext
text/x-wiki
Here we will go into more depth on what each of these projects would require:
==Migrating Swarm Client PID's to Firmware==
===Focus Area===
*Firmware Programming and Communication Protocols
**This project requires heavy modification of the Firmware and Communication systems inside the Crazyflie.
===Tasks===
====Firmware====
*'''(HARD)''' Modifying [https://wiki.bitcraze.io/projects:crazyflie:crtp:commander Commander Packet Structure] to allow position data to be sent rather than pitch, roll, yaw, and thrust setpoints.
*Modifying Firmware to pass the new position data into the correct place for use by the Firmware PID controllers.
====Client====
*Modify Swarm Client packet construction to match new commander packet protocol in Firmware
*'''(EASY)''' Remove Controllers from callbacks and just send location packets to Crazyflies while still maintaining other functionality.
===Benefits===
*Significantly reduces Client-side computation and allows Crazyflie swarm to share the load.
*Potential extension to completely independent Crazyflie flight (i.e. No Client needed at all)
==Tuning X, Y, and Z Location PID's for Faster Response==
==Adding Parameter Support to Swarm Client==
==Threading Each USB Radio to speed up Computation==
==Crazyflie Model Development and Verification==
==Developing New Controllers for the Crazyflie (pending Model Development)==
==Develop Communications Network Between Crazyflies==
==Trilateration Position Estimation using a Swarm==
----
<center> '''Main Directory''' </center>
<center> [[Crazyflie Swarm|Crazyflie Swarm Home]] | [[PC Client Software]] | [[USB Radio]] | [[Firmware]] | [[FAQ]] </center>
<center> '''Modifications Directory''' </center>
<center> [[Controller]] | [[Logging]] | [[Keyboard Commands]] | [[USB Radio#Changing Radio Channel|Changing Radio Channel]] | [[Flight Modes]] | [[Callbacks]] | [[Adding a Crazyflie]] | [[Firmware]] </center>
fc38c9df27be9233714d5e1d1d6d7ec468b48bc8
166
164
2016-07-28T19:08:41Z
Jnoronha
3
/* Tuning X, Y, and Z Location PID's for Faster Response */ finished section
wikitext
text/x-wiki
Here we will go into more depth on what each of these projects would require:
==Migrating Swarm Client PID's to Firmware==
===Focus Area===
*Firmware Programming and Communication Protocols
**This project requires heavy modification of the Firmware and Communication systems inside the Crazyflie.
===Tasks===
====Firmware====
*'''(HARD)''' Modifying [https://wiki.bitcraze.io/projects:crazyflie:crtp:commander Commander Packet Structure] to allow position data to be sent rather than pitch, roll, yaw, and thrust setpoints.
*Modifying Firmware to pass the new position data into the correct place for use by the Firmware PID controllers.
====Client====
*Modify Swarm Client packet construction to match new commander packet protocol in Firmware
*'''(EASY)''' Remove Controllers from callbacks and just send location packets to Crazyflies while still maintaining other functionality.
===Benefits===
*Significantly reduces Client-side computation and allows Crazyflie swarm to share the load.
*Potential extension to completely independent Crazyflie flight (i.e. No Client needed at all)
==Tuning X, Y, and Z Location PID's for Faster Response==
===Focus Area===
'''Control Systems and Model Development/Verification'''
*This project will require developing a model of the Crazyflie system and using the Model to calculate PID constants.
===Tasks===
*'''(HARD)''' Identify model Parameters for the Crazyflie
*Construct model in Simulink and Verify simulation compared to test data
*'''(EASY)''' Derive PID constants from verified model, test flight performance
===Benefits===
*'''VERIFIED MODEL!!''' We can do many things once we have a verified model of the system.
*Flight performance will be greatly improved allowing more complex applications to be developed.
*'''Potential extension:''' Path prediction algorithms and optimal pathing between points with obstacles
==Adding Parameter Support to Swarm Client==
==Threading Each USB Radio to speed up Computation==
==Crazyflie Model Development and Verification==
==Developing New Controllers for the Crazyflie (pending Model Development)==
==Develop Communications Network Between Crazyflies==
==Trilateration Position Estimation using a Swarm==
----
<center> '''Main Directory''' </center>
<center> [[Crazyflie Swarm|Crazyflie Swarm Home]] | [[PC Client Software]] | [[USB Radio]] | [[Firmware]] | [[FAQ]] </center>
<center> '''Modifications Directory''' </center>
<center> [[Controller]] | [[Logging]] | [[Keyboard Commands]] | [[USB Radio#Changing Radio Channel|Changing Radio Channel]] | [[Flight Modes]] | [[Callbacks]] | [[Adding a Crazyflie]] | [[Firmware]] </center>
a6d836255f0cdb40bdc11d406d726f4ffed46a6a
167
166
2016-07-28T19:09:26Z
Jnoronha
3
/* Migrating Swarm Client PID's to Firmware */ formatting
wikitext
text/x-wiki
Here we will go into more depth on what each of these projects would require:
==Migrating Swarm Client PID's to Firmware==
===Focus Area===
'''Firmware Programming and Communication Protocols'''
*This project requires heavy modification of the Firmware and Communication systems inside the Crazyflie.
===Tasks===
====Firmware====
*'''(HARD)''' Modifying [https://wiki.bitcraze.io/projects:crazyflie:crtp:commander Commander Packet Structure] to allow position data to be sent rather than pitch, roll, yaw, and thrust setpoints.
*Modifying Firmware to pass the new position data into the correct place for use by the Firmware PID controllers.
====Client====
*Modify Swarm Client packet construction to match new commander packet protocol in Firmware
*'''(EASY)''' Remove Controllers from callbacks and just send location packets to Crazyflies while still maintaining other functionality.
===Benefits===
*Significantly reduces Client-side computation and allows Crazyflie swarm to share the load.
*'''Potential extension:''' Completely independent Crazyflie flight (i.e. No Client needed at all)
==Tuning X, Y, and Z Location PID's for Faster Response==
===Focus Area===
'''Control Systems and Model Development/Verification'''
*This project will require developing a model of the Crazyflie system and using the Model to calculate PID constants.
===Tasks===
*'''(HARD)''' Identify model Parameters for the Crazyflie
*Construct model in Simulink and Verify simulation compared to test data
*'''(EASY)''' Derive PID constants from verified model, test flight performance
===Benefits===
*'''VERIFIED MODEL!!''' We can do many things once we have a verified model of the system.
*Flight performance will be greatly improved allowing more complex applications to be developed.
*'''Potential extension:''' Path prediction algorithms and optimal pathing between points with obstacles
==Adding Parameter Support to Swarm Client==
==Threading Each USB Radio to speed up Computation==
==Crazyflie Model Development and Verification==
==Developing New Controllers for the Crazyflie (pending Model Development)==
==Develop Communications Network Between Crazyflies==
==Trilateration Position Estimation using a Swarm==
----
<center> '''Main Directory''' </center>
<center> [[Crazyflie Swarm|Crazyflie Swarm Home]] | [[PC Client Software]] | [[USB Radio]] | [[Firmware]] | [[FAQ]] </center>
<center> '''Modifications Directory''' </center>
<center> [[Controller]] | [[Logging]] | [[Keyboard Commands]] | [[USB Radio#Changing Radio Channel|Changing Radio Channel]] | [[Flight Modes]] | [[Callbacks]] | [[Adding a Crazyflie]] | [[Firmware]] </center>
93ba24762e147af05bf44a9e3932dca78dccec24
173
167
2016-07-28T19:25:59Z
Jnoronha
3
/* Adding Parameter Support to Swarm Client */ finished section
wikitext
text/x-wiki
Here we will go into more depth on what each of these projects would require:
==Migrating Swarm Client PID's to Firmware==
===Focus Area===
'''Firmware Programming and Communication Protocols'''
*This project requires heavy modification of the Firmware and Communication systems inside the Crazyflie.
===Tasks===
====Firmware====
*'''(HARD)''' Modifying [https://wiki.bitcraze.io/projects:crazyflie:crtp:commander Commander Packet Structure] to allow position data to be sent rather than pitch, roll, yaw, and thrust setpoints.
*Modifying Firmware to pass the new position data into the correct place for use by the Firmware PID controllers.
====Client====
*Modify Swarm Client packet construction to match new commander packet protocol in Firmware
*'''(EASY)''' Remove Controllers from callbacks and just send location packets to Crazyflies while still maintaining other functionality.
===Benefits===
*Significantly reduces Client-side computation and allows Crazyflie swarm to share the load.
*'''Potential extension:''' Completely independent Crazyflie flight (i.e. No Client needed at all)
==Tuning X, Y, and Z Location PID's for Faster Response==
===Focus Area===
'''Control Systems and Model Development/Verification'''
*This project will require developing a model of the Crazyflie system and using the Model to calculate PID constants.
===Tasks===
*'''(HARD)''' Identify model Parameters for the Crazyflie
*Construct model in Simulink and Verify simulation compared to test data
*'''(EASY)''' Derive PID constants from verified model, test flight performance
===Benefits===
*'''VERIFIED MODEL!!''' We can do many things once we have a verified model of the system.
*Flight performance will be greatly improved allowing more complex applications to be developed.
*'''Potential extension:''' Path prediction algorithms and optimal pathing between points with obstacles
==Adding Parameter Support to Swarm Client==
===Focus Area===
'''Communications Protocols and Networking'''
*This project will require Client-side software development to create helper functions for easy modification of parameters on the Crazyflie Firmware
===Tasks===
*Creating packet framework in the Client to replicate the [https://wiki.bitcraze.io/projects:crazyflie:firmware:comm_protocol#parameters parameters packet protocol]
*Programming helper functions to make it simple to modify parameters
**Ex. Write Parameter Value: <code>setParam(string "param_group.param_name", int set_value);</code>
**Ex. Read Parameter Value: <code>readParam(string "param_group.param_name");</code>
===Benefits===
*Won't have to re-flash Firmware every time we want to test a parameter change (Improves Firmware testing efficiency)
*Less Firmware modification if we can just write params during Client init.
*'''Potential Extension:''' Tuning Firmware PID constants
==Threading Each USB Radio to speed up Computation==
==Crazyflie Model Development and Verification==
==Developing New Controllers for the Crazyflie (pending Model Development)==
==Develop Communications Network Between Crazyflies==
==Trilateration Position Estimation using a Swarm==
----
<center> '''Main Directory''' </center>
<center> [[Crazyflie Swarm|Crazyflie Swarm Home]] | [[PC Client Software]] | [[USB Radio]] | [[Firmware]] | [[FAQ]] </center>
<center> '''Modifications Directory''' </center>
<center> [[Controller]] | [[Logging]] | [[Keyboard Commands]] | [[USB Radio#Changing Radio Channel|Changing Radio Channel]] | [[Flight Modes]] | [[Callbacks]] | [[Adding a Crazyflie]] | [[Firmware]] </center>
ddf63c7686099987924458021b1e433d541bab19
174
173
2016-07-28T19:28:17Z
Jnoronha
3
changed title and spacing
wikitext
text/x-wiki
Here we will go into more depth on what each of these projects would require:
==Migrating Swarm Client PID's to Firmware==
===Focus Area===
'''Firmware Programming and Communication Protocols'''
*This project requires heavy modification of the Firmware and Communication systems inside the Crazyflie.
===Tasks===
====Firmware====
*'''(HARD)''' Modifying [https://wiki.bitcraze.io/projects:crazyflie:crtp:commander Commander Packet Structure] to allow position data to be sent rather than pitch, roll, yaw, and thrust setpoints.
*Modifying Firmware to pass the new position data into the correct place for use by the Firmware PID controllers.
====Client====
*Modify Swarm Client packet construction to match new commander packet protocol in Firmware
*'''(EASY)''' Remove Controllers from callbacks and just send location packets to Crazyflies while still maintaining other functionality.
===Benefits===
*Significantly reduces Client-side computation and allows Crazyflie swarm to share the load.
*'''Potential extension:''' Completely independent Crazyflie flight (i.e. No Client needed at all)
==Model Development/Verification and Tuning X, Y, and Z Location PID's==
===Focus Area===
'''Control Systems and Model Development/Verification'''
*This project will require developing a model of the Crazyflie system and using the Model to calculate PID constants.
===Tasks===
*'''(HARD)''' Identify model Parameters for the Crazyflie
*Construct model in Simulink and Verify simulation compared to test data
*'''(EASY)''' Derive PID constants from verified model, test flight performance
===Benefits===
*'''VERIFIED MODEL!!''' We can do many things once we have a verified model of the system.
*Flight performance will be greatly improved allowing more complex applications to be developed.
*'''Potential extension:''' Path prediction algorithms and optimal pathing between points with obstacles
==Adding Parameter Support to Swarm Client==
===Focus Area===
'''Communications Protocols and Networking'''
*This project will require Client-side software development to create helper functions for easy modification of parameters on the Crazyflie Firmware
===Tasks===
*Creating packet framework in the Client to replicate the [https://wiki.bitcraze.io/projects:crazyflie:firmware:comm_protocol#parameters parameters packet protocol]
*Programming helper functions to make it simple to modify parameters
**Ex. Write Parameter Value: <code>setParam(string "param_group.param_name", int set_value);</code>
**Ex. Read Parameter Value: <code>readParam(string "param_group.param_name");</code>
===Benefits===
*Won't have to re-flash Firmware every time we want to test a parameter change (Improves Firmware testing efficiency)
*Less Firmware modification if we can just write params during Client init.
*'''Potential Extension:''' Tuning Firmware PID constants
==Threading Each USB Radio to speed up Computation==
==Crazyflie Model Development and Verification==
==Developing New Controllers for the Crazyflie (pending Model Development)==
==Develop Communications Network Between Crazyflies==
==Trilateration Position Estimation using a Swarm==
----
<center> '''Main Directory''' </center>
<center> [[Crazyflie Swarm|Crazyflie Swarm Home]] | [[PC Client Software]] | [[USB Radio]] | [[Firmware]] | [[FAQ]] </center>
<center> '''Modifications Directory''' </center>
<center> [[Controller]] | [[Logging]] | [[Keyboard Commands]] | [[USB Radio#Changing Radio Channel|Changing Radio Channel]] | [[Flight Modes]] | [[Callbacks]] | [[Adding a Crazyflie]] | [[Firmware]] </center>
4c9de0a619154289f99b0550a16f76a190f9de7e
175
174
2016-07-28T19:29:04Z
Jnoronha
3
removed duplicate model development
wikitext
text/x-wiki
Here we will go into more depth on what each of these projects would require:
==Migrating Swarm Client PID's to Firmware==
===Focus Area===
'''Firmware Programming and Communication Protocols'''
*This project requires heavy modification of the Firmware and Communication systems inside the Crazyflie.
===Tasks===
====Firmware====
*'''(HARD)''' Modifying [https://wiki.bitcraze.io/projects:crazyflie:crtp:commander Commander Packet Structure] to allow position data to be sent rather than pitch, roll, yaw, and thrust setpoints.
*Modifying Firmware to pass the new position data into the correct place for use by the Firmware PID controllers.
====Client====
*Modify Swarm Client packet construction to match new commander packet protocol in Firmware
*'''(EASY)''' Remove Controllers from callbacks and just send location packets to Crazyflies while still maintaining other functionality.
===Benefits===
*Significantly reduces Client-side computation and allows Crazyflie swarm to share the load.
*'''Potential extension:''' Completely independent Crazyflie flight (i.e. No Client needed at all)
==Model Development/Verification and Tuning X, Y, and Z Location PID's==
===Focus Area===
'''Control Systems and Model Development/Verification'''
*This project will require developing a model of the Crazyflie system and using the Model to calculate PID constants.
===Tasks===
*'''(HARD)''' Identify model Parameters for the Crazyflie
*Construct model in Simulink and Verify simulation compared to test data
*'''(EASY)''' Derive PID constants from verified model, test flight performance
===Benefits===
*'''VERIFIED MODEL!!''' We can do many things once we have a verified model of the system.
*Flight performance will be greatly improved allowing more complex applications to be developed.
*'''Potential extension:''' Path prediction algorithms and optimal pathing between points with obstacles
==Adding Parameter Support to Swarm Client==
===Focus Area===
'''Communications Protocols and Networking'''
*This project will require Client-side software development to create helper functions for easy modification of parameters on the Crazyflie Firmware
===Tasks===
*Creating packet framework in the Client to replicate the [https://wiki.bitcraze.io/projects:crazyflie:firmware:comm_protocol#parameters parameters packet protocol]
*Programming helper functions to make it simple to modify parameters
**Ex. Write Parameter Value: <code>setParam(string "param_group.param_name", int set_value);</code>
**Ex. Read Parameter Value: <code>readParam(string "param_group.param_name");</code>
===Benefits===
*Won't have to re-flash Firmware every time we want to test a parameter change (Improves Firmware testing efficiency)
*Less Firmware modification if we can just write params during Client init.
*'''Potential Extension:''' Tuning Firmware PID constants
==Threading Each USB Radio to speed up Computation==
==Developing New Controllers for the Crazyflie (pending Model Development)==
==Develop Communications Network Between Crazyflies==
==Trilateration Position Estimation using a Swarm==
----
<center> '''Main Directory''' </center>
<center> [[Crazyflie Swarm|Crazyflie Swarm Home]] | [[PC Client Software]] | [[USB Radio]] | [[Firmware]] | [[FAQ]] </center>
<center> '''Modifications Directory''' </center>
<center> [[Controller]] | [[Logging]] | [[Keyboard Commands]] | [[USB Radio#Changing Radio Channel|Changing Radio Channel]] | [[Flight Modes]] | [[Callbacks]] | [[Adding a Crazyflie]] | [[Firmware]] </center>
60fb278599b0974720dda95cfe9121d8e5fc86d3
176
175
2016-07-28T19:55:56Z
Jnoronha
3
/* Threading Each USB Radio to speed up Computation */ completed
wikitext
text/x-wiki
Here we will go into more depth on what each of these projects would require:
==Migrating Swarm Client PID's to Firmware==
===Focus Area===
'''Firmware Programming and Communication Protocols'''
*This project requires heavy modification of the Firmware and Communication systems inside the Crazyflie.
===Tasks===
====Firmware====
*'''(HARD)''' Modifying [https://wiki.bitcraze.io/projects:crazyflie:crtp:commander Commander Packet Structure] to allow position data to be sent rather than pitch, roll, yaw, and thrust setpoints.
*Modifying Firmware to pass the new position data into the correct place for use by the Firmware PID controllers.
====Client====
*Modify Swarm Client packet construction to match new commander packet protocol in Firmware
*'''(EASY)''' Remove Controllers from callbacks and just send location packets to Crazyflies while still maintaining other functionality.
===Benefits===
*Significantly reduces Client-side computation and allows Crazyflie swarm to share the load.
*'''Potential extension:''' Completely independent Crazyflie flight (i.e. No Client needed at all)
==Model Development/Verification and Tuning X, Y, and Z Location PID's==
===Focus Area===
'''Control Systems and Model Development/Verification'''
*This project will require developing a model of the Crazyflie system and using the Model to calculate PID constants.
===Tasks===
*'''(HARD)''' Identify model Parameters for the Crazyflie
*Construct model in Simulink and Verify simulation compared to test data
*'''(EASY)''' Derive PID constants from verified model, test flight performance
===Benefits===
*'''VERIFIED MODEL!!''' We can do many things once we have a verified model of the system.
*Flight performance will be greatly improved allowing more complex applications to be developed.
*'''Potential extension:''' Path prediction algorithms and optimal pathing between points with obstacles
==Adding Parameter Support to Swarm Client==
===Focus Area===
'''Communications Protocols and Networking'''
*This project will require Client-side software development to create helper functions for easy modification of parameters on the Crazyflie Firmware
===Tasks===
*Creating packet framework in the Client to replicate the [https://wiki.bitcraze.io/projects:crazyflie:firmware:comm_protocol#parameters parameters packet protocol]
*Programming helper functions to make it simple to modify parameters
**Ex. Write Parameter Value: <code>setParam(string "param_group.param_name", int set_value);</code>
**Ex. Read Parameter Value: <code>readParam(string "param_group.param_name");</code>
===Benefits===
*Won't have to re-flash Firmware every time we want to test a parameter change (Improves Firmware testing efficiency)
*Less Firmware modification if we can just write params during Client init.
*'''Potential Extension:''' Tuning Firmware PID constants
==Threading Each USB Radio to speed up Computation==
===Focus Area===
'''Computer Architecture and Parallelization'''
*This project will require/develop a good understanding of parallel processing and computer architecture.
===Tasks===
*Apply threading to each USB Radio individually
**A single Radio will be assigned at most 3 Crazyflies, and each thread will handle the corresponding Callbacks for those Crazyflies (which includes control calculations, Radio communications, and logging for each Crazyflie)
*Troubleshoot any issues that come up with non-sequential program execution (shouldn't have problems)
===Benefits===
*Greatly reduces time required to complete a loop cycle (relative to number of Crazyflies in the Swarm)
**Improves scalability of the Swarm since we don't need to worry about missing the Camera System new data timing deadline as the Swarm size increases
*'''Potential Extension:''' Increasing Swarm size to Camera System capacity limit.
==Developing New Controllers for the Crazyflie (pending Model Development)==
==Develop Communications Network Between Crazyflies==
==Trilateration Position Estimation using a Swarm==
----
<center> '''Main Directory''' </center>
<center> [[Crazyflie Swarm|Crazyflie Swarm Home]] | [[PC Client Software]] | [[USB Radio]] | [[Firmware]] | [[FAQ]] </center>
<center> '''Modifications Directory''' </center>
<center> [[Controller]] | [[Logging]] | [[Keyboard Commands]] | [[USB Radio#Changing Radio Channel|Changing Radio Channel]] | [[Flight Modes]] | [[Callbacks]] | [[Adding a Crazyflie]] | [[Firmware]] </center>
5babe2b06e38b78f59e64c5a25e67541b257925b
Using Robotic Agriculture Data Acquisition (RADA) for Research Use
0
48
165
2016-07-28T19:07:53Z
Pfuhing
5
New page: This page discusses the RADA platform for research used. If you want information about the RADA platform see [http://wikis.ece.iastate.edu/robotic-agriculture-data-acquisition/index.php/Ma...
wikitext
text/x-wiki
This page discusses the RADA platform for research used. If you want information about the RADA platform see [http://wikis.ece.iastate.edu/robotic-agriculture-data-acquisition/index.php/Main_Page RADA Senior Design Project].
This page will discuss two important issues for using the RADA platform for research:
0cc541ea9253120a4eb228ced7944f04ddfdd39d
168
165
2016-07-28T19:09:56Z
Pfuhing
5
[[Robotic Agriculture Data Acquisition (RADA)]] moved to [[Using Robotic Agriculture Data Acquisition (RADA) for Research Use]]: There is already a wiki for the RADA platform designed by a ECpE senior design team so the pages could get confusing
wikitext
text/x-wiki
This page discusses the RADA platform for research used. If you want information about the RADA platform see [http://wikis.ece.iastate.edu/robotic-agriculture-data-acquisition/index.php/Main_Page RADA Senior Design Project].
This page will discuss two important issues for using the RADA platform for research:
0cc541ea9253120a4eb228ced7944f04ddfdd39d
170
168
2016-07-28T19:13:24Z
Pfuhing
5
wikitext
text/x-wiki
This page discusses the RADA platform for research used. If you want information about the RADA platform see [http://wikis.ece.iastate.edu/robotic-agriculture-data-acquisition/index.php/Main_Page RADA Senior Design Project].
This page will discuss two important issues for using the RADA platform for research:
[[Data Collection and Simulation Comparison]]
7da2e657cc615e5edbcc4d8f008a9edd1e02efb8
171
170
2016-07-28T19:15:40Z
Pfuhing
5
wikitext
text/x-wiki
This page discusses the RADA platform for research used. If you want information about the RADA platform see [http://wikis.ece.iastate.edu/robotic-agriculture-data-acquisition/index.php/Main_Page RADA Senior Design Project].
This page will discuss two important issues for using the RADA platform for research:
[[Data Collection and Simulation Comparison]]
[[Setting up and Modifying RADA Simulations]]
67c813c5f63a5b763c72610cd093cf2db2fada4b
172
171
2016-07-28T19:20:40Z
Pfuhing
5
wikitext
text/x-wiki
This page discusses the RADA platform for research used. If you want information about the RADA platform see [http://wikis.ece.iastate.edu/robotic-agriculture-data-acquisition/index.php/Main_Page RADA Senior Design Project].
This page will discuss two important issues for using the RADA platform for research:
*[[Data Collection and Simulation Comparison]]
*[[Setting up and Modifying RADA Simulations]]
The page on data collection and simulation comparison will discus how to set a test of RADA and then take the logged data and compare it to a simulation of RADA in Simulink using the model developed for Paul Uhing's thesis. While the page on setting up and modifing RADA simulations will discuss how RADA Simulink simulations are currently structured and other important information for creating your own Simulink simulations of RADA.
086138a5c9ed2365ec2d4a88a5cb83a0f9f45b47
Robotic Agriculture Data Acquisition (RADA)
0
49
169
2016-07-28T19:09:56Z
Pfuhing
5
[[Robotic Agriculture Data Acquisition (RADA)]] moved to [[Using Robotic Agriculture Data Acquisition (RADA) for Research Use]]: There is already a wiki for the RADA platform designed by a ECpE senior design team so the pages could get confusing
wikitext
text/x-wiki
#REDIRECT [[Using Robotic Agriculture Data Acquisition (RADA) for Research Use]]
5d9cf3c6ce57071342a9c5a3b38d8e10104b1056
Crazyflie Swarm
0
2
177
130
2016-07-28T20:02:55Z
Jnoronha
3
/* Future Project Ideas */ linked all future projects to detailed section
wikitext
text/x-wiki
The Crazyflie Swarm is a Networked Control platform designed for students to learn more about control and for researchers that wish to apply their research in practice. Platform development was started during the Summer of 2015 and continues to this day.
Here you will find descriptions on how the platform works, how you can use it, and how you can get involved in developing the platform further!
== Frequently Asked Questions ==
For help with common problems and troubleshooting please see the [[FAQ]].
== Background ==
The Crazyflie Swarm platform is based off of the ''Crazyflie'' Nano-quadcopter produced and maintained by [https://www.bitcraze.io/ Bitcraze]. The ''Crazyflie'' is completely open-source so we are able to look at and modify any part of the code and customize it to our needs.
=== Major Platform Components: ===
[[Image: High_Level_Figure_(Single_Radio_Single_Crazyflie_NO_NUMBERS_CROPPED).jpg|thumb|right|A high level overview of the Crazyflie Platform]]
*[[PC Client Software]]
*[[Firmware]]
*[[USB Radio]]
== Modifying the Platform ==
*[[Controller]]
*[[Logging]]
*[[Keyboard Commands]]
*[[USB Radio#Changing Radio Channel|Changing Radio Channel]]
*[[Flight Modes]]
*[[Callbacks]]
*[[Adding a Crazyflie]]
*[[:Firmware]]
==Future Project Ideas==
The whole concept of this Platform is to constantly expand its capabilities. If you are interested in developing this platform further here are some ideas to get you started! Additional details on any of these ideas can be found on the [[Future Project Ideas]] page.
*[[:Future Project Ideas#Migrating Swarm Client PID's to Firmware|Migrating Swarm Client PID's to Firmware]]
*[[:Future Project Ideas#Model Development/Verification and Tuning X, Y, and Z Location PID's|Model Development/Verification and Tuning X, Y, and Z Location PID's]]
*[[:Future Project Ideas#Adding Parameter Support to Swarm Client|Adding Parameter Support to Swarm Client]]
*[[:Future Project Ideas#Threading Each USB Radio to speed up Computation|Threading Each USB Radio to speed up Computation]]
*[[:Future Project Ideas#Developing New Controllers for the Crazyflie (pending Model Development)|Developing New Controllers for the Crazyflie (pending Model Development)]]
*[[:Future Project Ideas#Develop Communications Network Between Crazyflies|Develop Communications Network Between Crazyflies]]
*[[:Future Project Ideas#Trilateration Position Estimation using a Swarm|Trilateration Position Estimation using a Swarm]]
== [https://wiki.bitcraze.io/ Bitcraze Wiki] ==
Bitcraze maintains their own wiki on the many Crazyflie systems. If you can't find what you are looking for here, chances are they will have something to help.
62a25abdef765390632d834cd4275d7928c13cda
Data Collection and Simulation Comparison
0
50
178
2016-08-01T18:49:31Z
Pfuhing
5
New page: '''Setting Up a RADA Test''' ----
wikitext
text/x-wiki
'''Setting Up a RADA Test'''
----
d2029e49fadfe80ffa3887c8accc48e88d58d2f2
179
178
2016-08-01T18:50:17Z
Pfuhing
5
wikitext
text/x-wiki
This
'''Setting Up a RADA Test'''
----
526991677210742543a05c5bc11e23ee3297bcb3
180
179
2016-08-01T18:55:00Z
Pfuhing
5
wikitext
text/x-wiki
This page will take you though setting up and testing RADA, retrieving the log file and other necessary data to run a simulation of that test and processing the data in MATLAB. Then actually running the simulation of RADA in Simulink.
== Setting Up a RADA Test ==
e3bccf8523f70597e854b771f4a0c756f7dde6ac
181
180
2016-08-01T19:06:56Z
Pfuhing
5
wikitext
text/x-wiki
This page will take you though setting up and testing RADA, retrieving the log file and other necessary data to run a simulation of that test and processing the data in MATLAB. Then actually running the simulation of RADA in Simulink.
== Setting Up a RADA Test ==
=== Charging batteries ===
=== Setting up the camera system ===
=== Building Software ===
=== Turing on RADA ===
=== Connecting to RADA ===
== Testing RADA ==
=== Running the first test after power up ===
=== Running additional tests ===
=== Measuring battery voltages ===
=== Locating and retrieving log files ===
== Post processing and Simulation ==
=== Using the MATLAB data parsing tool ===
=== Adding additional data for simulations ===
=== Setting up the MATLAB work space for simulation ===
=== Running simulations and storing results ===
=== Plotting results ===
4f0e8ae541549903e5fc046f5fc3cb61bb427e72
182
181
2016-08-01T19:40:07Z
Pfuhing
5
wikitext
text/x-wiki
This page will take you though setting up and testing RADA, retrieving the log file and other necessary data to run a simulation of that test and processing the data in MATLAB. Then actually running the simulation of RADA in Simulink.
== Setting Up a RADA Test ==
Testing RADA is not overly difficult once you get the hang of the steps to setup RADA. The following steps may seem like a long process to go from starting the testing process to having completed simulation and plotting of the test results but this whole test procedure (with the exception of battery charging) can be completed in about 15-20 minutes. These steps are meant to be as detailed as possible in order to help new users of RADA to get up and running as quickly as possible.
'''<span style="color:red">NOTE: Always run RADA with at least 2 people!</span>''' The pendulum arm can crash into the ground if the network starts to drop packets and one person cannot give commands to RADA and spot the pendulum. This is a safety issue for both you and the RADA platform.
=== Charging batteries ===
The lab currently uses mostly Hyperion batteries. We charge our batteries with a Hyperion EOS 1420i Net3 battery charger. For some general information about how to use this charger see [https://www.youtube.com/watch?v=-ox3EpzvsJ8 this video.]. In the lab we power this charger using the old Kepco Power supplu because it is the only power supply that we have that can supply enough current. Make sure that the power supply is set to an output voltage between 10.5V-29V.
[[Image: High_Level_Figure_(Single_Radio_Single_Crazyflie_NO_NUMBERS_CROPPED).jpg|thumb|right|A high level overview of the Crazyflie Platform]]
=== Setting up the camera system ===
=== Building Software ===
=== Turing on RADA ===
=== Connecting to RADA ===
== Testing RADA ==
=== Running the first test after power up ===
=== Running additional tests ===
=== Measuring battery voltages ===
=== Locating and retrieving log files ===
== Post processing and Simulation ==
=== Using the MATLAB data parsing tool ===
=== Adding additional data for simulations ===
=== Setting up the MATLAB workspace for simulation ===
=== Running simulations and storing results ===
=== Plotting results ===
ac842f683442d9a4ff0e12445e8dc3ed3bacbd4f
185
182
2016-08-01T19:55:28Z
Pfuhing
5
wikitext
text/x-wiki
This page will take you though setting up and testing RADA, retrieving the log file and other necessary data to run a simulation of that test and processing the data in MATLAB. Then actually running the simulation of RADA in Simulink.
== Setting Up a RADA Test ==
Testing RADA is not overly difficult once you get the hang of the steps to setup RADA. The following steps may seem like a long process to go from starting the testing process to having completed simulation and plotting of the test results but this whole test procedure (with the exception of battery charging) can be completed in about 15-20 minutes. These steps are meant to be as detailed as possible in order to help new users of RADA to get up and running as quickly as possible.
'''<span style="color:red">NOTE: Always run RADA with at least 2 people!</span>''' The pendulum arm can crash into the ground if the network starts to drop packets and one person cannot give commands to RADA and spot the pendulum. This is a safety issue for both you and the RADA platform.
=== Charging batteries ===
The lab currently uses mostly Hyperion batteries. We charge our batteries with a Hyperion EOS 1420i Net3 battery charger. For some general information about how to use this charger see [https://www.youtube.com/watch?v=-ox3EpzvsJ8 this video.]. In the lab we power this charger using the old Kepco Power supplu because it is the only power supply that we have that can supply enough current. Make sure that the power supply is set to an output voltage between 10.5V-29V.
[[Image:ChargerPowerSuplyOff.JPG|thumb|right|Kepco Power Supply off]]
=== Setting up the camera system ===
=== Building Software ===
=== Turing on RADA ===
=== Connecting to RADA ===
== Testing RADA ==
=== Running the first test after power up ===
=== Running additional tests ===
=== Measuring battery voltages ===
=== Locating and retrieving log files ===
== Post processing and Simulation ==
=== Using the MATLAB data parsing tool ===
=== Adding additional data for simulations ===
=== Setting up the MATLAB workspace for simulation ===
=== Running simulations and storing results ===
=== Plotting results ===
5725d1cca5781a6db4d7704b248b41d2f9680b37
191
185
2016-08-01T20:15:36Z
Pfuhing
5
wikitext
text/x-wiki
This page will take you though setting up and testing RADA, retrieving the log file and other necessary data to run a simulation of that test and processing the data in MATLAB. Then actually running the simulation of RADA in Simulink.
== Setting Up a RADA Test ==
Testing RADA is not overly difficult once you get the hang of the steps to setup RADA. The following steps may seem like a long process to go from starting the testing process to having completed simulation and plotting of the test results but this whole test procedure (with the exception of battery charging) can be completed in about 15-20 minutes. These steps are meant to be as detailed as possible in order to help new users of RADA to get up and running as quickly as possible.
'''<span style="color:red">NOTE: Always run RADA with at least 2 people!</span>''' The pendulum arm can crash into the ground if the network starts to drop packets and one person cannot give commands to RADA and spot the pendulum. This is a safety issue for both you and the RADA platform.
=== Charging batteries ===
The lab currently uses mostly Hyperion batteries. We charge our batteries with a Hyperion EOS 1420i Net3 battery charger. For some general information about how to use this charger see [https://www.youtube.com/watch?v=-ox3EpzvsJ8 this video.]. In the lab we power this charger using the old Kepco Power supplu because it is the only power supply that we have that can supply enough current. Make sure that the power supply is set to an output voltage between 10.5V-29V.
{| class="wikitable" style="text-align:center"
|-
| [[Image:ChargerPowerSupplyOff.JPG|120px]]
| [[Image:ChargerPowerSuplyOn.JPG|120px]]
|-
| Kepco Power Supply off
| Kepco Power Supply on with correct voltage supply range.
|}
=== Setting up the camera system ===
=== Building Software ===
=== Turing on RADA ===
=== Connecting to RADA ===
== Testing RADA ==
=== Running the first test after power up ===
=== Running additional tests ===
=== Measuring battery voltages ===
=== Locating and retrieving log files ===
== Post processing and Simulation ==
=== Using the MATLAB data parsing tool ===
=== Adding additional data for simulations ===
=== Setting up the MATLAB workspace for simulation ===
=== Running simulations and storing results ===
=== Plotting results ===
bb0bb1af6f8d4449213b9aed0fe20e46cbd71b12
193
191
2016-08-01T20:17:19Z
Pfuhing
5
wikitext
text/x-wiki
This page will take you though setting up and testing RADA, retrieving the log file and other necessary data to run a simulation of that test and processing the data in MATLAB. Then actually running the simulation of RADA in Simulink.
== Setting Up a RADA Test ==
Testing RADA is not overly difficult once you get the hang of the steps to setup RADA. The following steps may seem like a long process to go from starting the testing process to having completed simulation and plotting of the test results but this whole test procedure (with the exception of battery charging) can be completed in about 15-20 minutes. These steps are meant to be as detailed as possible in order to help new users of RADA to get up and running as quickly as possible.
'''<span style="color:red">NOTE: Always run RADA with at least 2 people!</span>''' The pendulum arm can crash into the ground if the network starts to drop packets and one person cannot give commands to RADA and spot the pendulum. This is a safety issue for both you and the RADA platform.
=== Charging batteries ===
The lab currently uses mostly Hyperion batteries. We charge our batteries with a Hyperion EOS 1420i Net3 battery charger. For some general information about how to use this charger see [https://www.youtube.com/watch?v=-ox3EpzvsJ8 this video.]. In the lab we power this charger using the old Kepco Power supplu because it is the only power supply that we have that can supply enough current. Make sure that the power supply is set to an output voltage between 10.5V-29V.
{| class="wikitable" style="text-align:center"
|-
| [[Image:ChargerPowerSupplyOff.JPG|400px]]
| [[Image:ChargerPowerSuplyOn.JPG|400px]]
|-
| Kepco Power Supply off.
| Kepco Power Supply on with correct voltage supply range.
|}
=== Setting up the camera system ===
=== Building Software ===
=== Turing on RADA ===
=== Connecting to RADA ===
== Testing RADA ==
=== Running the first test after power up ===
=== Running additional tests ===
=== Measuring battery voltages ===
=== Locating and retrieving log files ===
== Post processing and Simulation ==
=== Using the MATLAB data parsing tool ===
=== Adding additional data for simulations ===
=== Setting up the MATLAB workspace for simulation ===
=== Running simulations and storing results ===
=== Plotting results ===
b14521faf68f4b08bd786b1820fa6f21f5553bf3
194
193
2016-08-01T20:26:14Z
Pfuhing
5
wikitext
text/x-wiki
This page will take you though setting up and testing RADA, retrieving the log file and other necessary data to run a simulation of that test and processing the data in MATLAB. Then actually running the simulation of RADA in Simulink.
== Setting Up a RADA Test ==
Testing RADA is not overly difficult once you get the hang of the steps to setup RADA. The following steps may seem like a long process to go from starting the testing process to having completed simulation and plotting of the test results but this whole test procedure (with the exception of battery charging) can be completed in about 15-20 minutes. These steps are meant to be as detailed as possible in order to help new users of RADA to get up and running as quickly as possible.
'''<span style="color:red">NOTE: Always run RADA with at least 2 people!</span>''' The pendulum arm can crash into the ground if the network starts to drop packets and one person cannot give commands to RADA and spot the pendulum. This is a safety issue for both you and the RADA platform.
=== Charging batteries ===
The lab currently uses mostly Hyperion batteries. We charge our batteries with a Hyperion EOS 1420i Net3 battery charger. For some general information about how to use this charger see [https://www.youtube.com/watch?v=-ox3EpzvsJ8 this video.]. In the lab we power this charger using the old Kepco Power supplu because it is the only power supply that we have that can supply enough current. Make sure that the power supply is set to an output voltage between 10.5V-29V.
{| class="wikitable" style="text-align:center"
|-
| [[Image:ChargerPowerSupplyOff.JPG|400px]]
| [[Image:ChargerPowerSuplyOn.JPG|400px]]
|-
| Kepco Power Supply off.
| Kepco Power Supply on with correct voltage supply range.
|}
While the YouTube video linked above should explain how to use the charger. Currently three different Lithium polymer batteries (Lipo): 1600 mAh 2-cell Lipo for the wheels, 2600 mAh 2-cell Lipo for the electronics of Eris, and a 2600 mAh 4-cell Lipo. The 1600 mAh 2-cell Lipo can be charged using memory slot 2 of the charger. The 2600 mAh 2-cell Lipos can be charged using memory slot 3 for fast charging and memory slot 4 for slower charging (use this if the battery gets run really low for 10-20 minutes then switch to fast charging). The 2600 mAh 4-cell Lipo can be charged using memory slot 8. The 1600 mAh 2-cell and 2600 mAr 4-cell generally charge in 10-20 minutes apiece while I generally fine it takes the 2600 mAh 2-cell up to 70 minutes to charge fully.
=== Setting up the camera system ===
=== Building Software ===
=== Turing on RADA ===
=== Connecting to RADA ===
== Testing RADA ==
=== Running the first test after power up ===
=== Running additional tests ===
=== Measuring battery voltages ===
=== Locating and retrieving log files ===
== Post processing and Simulation ==
=== Using the MATLAB data parsing tool ===
=== Adding additional data for simulations ===
=== Setting up the MATLAB workspace for simulation ===
=== Running simulations and storing results ===
=== Plotting results ===
b64a26ddc5023f2fab735a418876e13c022886c1
File:ChargerPowerSupplyOff.JPG
6
51
183
2016-08-01T19:41:25Z
Pfuhing
5
Charging battery help
wikitext
text/x-wiki
Charging battery help
3b2df7503b8c991c002decc5e33da101c1d8529b
186
183
2016-08-01T20:01:06Z
Pfuhing
5
uploaded a new version of "[[Image:ChargerPowerSupplyOff.JPG]]"
wikitext
text/x-wiki
Charging battery help
3b2df7503b8c991c002decc5e33da101c1d8529b
187
186
2016-08-01T20:02:01Z
Pfuhing
5
wikitext
text/x-wiki
{{Rotate |degree=90 }}
Charging battery help
e51caeb9a637e1fa85fc6b001557c2613c283549
188
187
2016-08-01T20:02:16Z
Pfuhing
5
wikitext
text/x-wiki
{{Rotate |degree=90 }}Charging battery help
e3646ca64bb9f640ee7eb1610c4afcd228e60467
189
188
2016-08-01T20:05:12Z
Pfuhing
5
uploaded a new version of "[[Image:ChargerPowerSupplyOff.JPG]]"
wikitext
text/x-wiki
{{Rotate |degree=90 }}Charging battery help
e3646ca64bb9f640ee7eb1610c4afcd228e60467
190
189
2016-08-01T20:09:55Z
Pfuhing
5
uploaded a new version of "[[Image:ChargerPowerSupplyOff.JPG]]"
wikitext
text/x-wiki
{{Rotate |degree=90 }}Charging battery help
e3646ca64bb9f640ee7eb1610c4afcd228e60467
File:ChargerPowerSuplyOn.JPG
6
52
184
2016-08-01T19:42:01Z
Pfuhing
5
charging help
wikitext
text/x-wiki
charging help
9b31ff62f8d68aa89f96952e188a204c71e3d34d
192
184
2016-08-01T20:15:56Z
Pfuhing
5
uploaded a new version of "[[Image:ChargerPowerSuplyOn.JPG]]"
wikitext
text/x-wiki
charging help
9b31ff62f8d68aa89f96952e188a204c71e3d34d
File:TrackingTools shortcut.PNG
6
53
195
2016-08-01T20:28:54Z
Pfuhing
5
image of tracking tools short cut
wikitext
text/x-wiki
image of tracking tools short cut
bc1a7751159915d63891137515d0c1adfef1a622
File:NewTrackingTools.PNG
6
54
196
2016-08-01T20:31:15Z
Pfuhing
5
Opening tracking tools
wikitext
text/x-wiki
Opening tracking tools
c5f6b14de4a006d80563f6b63fceca69522ac48c
File:OpeningProject.PNG
6
55
197
2016-08-01T20:31:58Z
Pfuhing
5
Open a tracking tools project
wikitext
text/x-wiki
Open a tracking tools project
e22b4d0ce5b40fb5c1a9cd40f9ffde1e0f1c15f9
File:Opening trackables.PNG
6
56
198
2016-08-01T20:33:57Z
Pfuhing
5
open trackable constellations saved as a separate file
wikitext
text/x-wiki
open trackable constellations saved as a separate file
1e27513b37350634e4140335c5ea561b2dc75052
File:SelectingUAV.PNG
6
57
199
2016-08-01T20:36:16Z
Pfuhing
5
Selecting a teckable constellation
wikitext
text/x-wiki
Selecting a teckable constellation
2aa4e817d01badeeff30392e6b023dc91150ccac
File:Uav realTimeInfo.PNG
6
58
200
2016-08-01T20:36:57Z
Pfuhing
5
checking the current orrientaiton of a trackable
wikitext
text/x-wiki
checking the current orrientaiton of a trackable
f6e56b04d94660fc09a4d6f31604c098571143d4
File:Uav ResetOrientation.PNG
6
59
201
2016-08-01T20:40:40Z
Pfuhing
5
Reset orientation of constellation
wikitext
text/x-wiki
Reset orientation of constellation
5cd1cd1bef7bc60c71010f19d247996033d94d11
Data Collection and Simulation Comparison
0
50
202
194
2016-08-01T20:53:28Z
Pfuhing
5
wikitext
text/x-wiki
This page will take you though setting up and testing RADA, retrieving the log file and other necessary data to run a simulation of that test and processing the data in MATLAB. Then actually running the simulation of RADA in Simulink.
== Setting Up a RADA Test ==
Testing RADA is not overly difficult once you get the hang of the steps to setup RADA. The following steps may seem like a long process to go from starting the testing process to having completed simulation and plotting of the test results but this whole test procedure (with the exception of battery charging) can be completed in about 15-20 minutes. These steps are meant to be as detailed as possible in order to help new users of RADA to get up and running as quickly as possible.
'''<span style="color:red">NOTE: Always run RADA with at least 2 people!</span>''' The pendulum arm can crash into the ground if the network starts to drop packets and one person cannot give commands to RADA and spot the pendulum. This is a safety issue for both you and the RADA platform.
=== Charging batteries ===
The lab currently uses mostly Hyperion batteries. We charge our batteries with a Hyperion EOS 1420i Net3 battery charger. For some general information about how to use this charger see [https://www.youtube.com/watch?v=-ox3EpzvsJ8 this video.]. In the lab we power this charger using the old Kepco Power supplu because it is the only power supply that we have that can supply enough current. Make sure that the power supply is set to an output voltage between 10.5V-29V.
{| class="wikitable" style="text-align:center"
|-
| [[Image:ChargerPowerSupplyOff.JPG|400px]]
| [[Image:ChargerPowerSuplyOn.JPG|400px]]
|-
| Kepco Power Supply off.
| Kepco Power Supply on with correct voltage supply range.
|}
While the YouTube video linked above should explain how to use the charger. Currently three different Lithium polymer batteries (Lipo): 1600 mAh 2-cell Lipo for the wheels, 2600 mAh 2-cell Lipo for the electronics of Eris, and a 2600 mAh 4-cell Lipo. The 1600 mAh 2-cell Lipo can be charged using memory slot 2 of the charger. The 2600 mAh 2-cell Lipos can be charged using memory slot 3 for fast charging and memory slot 4 for slower charging (use this if the battery gets run really low for 10-20 minutes then switch to fast charging). The 2600 mAh 4-cell Lipo can be charged using memory slot 8. The 1600 mAh 2-cell and 2600 mAr 4-cell generally charge in 10-20 minutes apiece while I generally fine it takes the 2600 mAh 2-cell up to 70 minutes to charge fully.
=== Setting up the camera system ===
The camera system is run on the windows computer CO3050-07. You can log into this computer using a local microcart username and password which is not posted here for security reasons but any one who works in the lab should know it. Once logged in look for Tracking TOlls in the start menu or look for the shortcut shown below:
[[Image:TrackingTools_shortcut.PNG|thumb|left|Tracking Tools shortcut]]
=== Building Software ===
=== Turing on RADA ===
=== Connecting to RADA ===
== Testing RADA ==
=== Running the first test after power up ===
=== Running additional tests ===
=== Measuring battery voltages ===
=== Locating and retrieving log files ===
== Post processing and Simulation ==
=== Using the MATLAB data parsing tool ===
=== Adding additional data for simulations ===
=== Setting up the MATLAB workspace for simulation ===
=== Running simulations and storing results ===
=== Plotting results ===
36defb4796fb92832ce0d5905d339343d27f6bfa
203
202
2016-08-01T21:50:46Z
Pfuhing
5
wikitext
text/x-wiki
This page will take you though setting up and testing RADA, retrieving the log file and other necessary data to run a simulation of that test and processing the data in MATLAB. Then actually running the simulation of RADA in Simulink.
== Setting Up a RADA Test ==
Testing RADA is not overly difficult once you get the hang of the steps to setup RADA. The following steps may seem like a long process to go from starting the testing process to having completed simulation and plotting of the test results but this whole test procedure (with the exception of battery charging) can be completed in about 15-20 minutes. These steps are meant to be as detailed as possible in order to help new users of RADA to get up and running as quickly as possible.
'''<span style="color:red">NOTE: Always run RADA with at least 2 people!</span>''' The pendulum arm can crash into the ground if the network starts to drop packets and one person cannot give commands to RADA and spot the pendulum. This is a safety issue for both you and the RADA platform.
=== Charging batteries ===
The lab currently uses mostly Hyperion batteries. We charge our batteries with a Hyperion EOS 1420i Net3 battery charger. For some general information about how to use this charger see [https://www.youtube.com/watch?v=-ox3EpzvsJ8 this video.]. In the lab we power this charger using the old Kepco Power supplu because it is the only power supply that we have that can supply enough current. Make sure that the power supply is set to an output voltage between 10.5V-29V.
{| class="wikitable" style="text-align:center"
|-
| [[Image:ChargerPowerSupplyOff.JPG|400px]]
| [[Image:ChargerPowerSuplyOn.JPG|400px]]
|-
| Kepco Power Supply off.
| Kepco Power Supply on with correct voltage supply range.
|}
While the YouTube video linked above should explain how to use the charger. Currently three different Lithium polymer batteries (Lipo): 1600 mAh 2-cell Lipo for the wheels, 2600 mAh 2-cell Lipo for the electronics of Eris, and a 2600 mAh 4-cell Lipo. The 1600 mAh 2-cell Lipo can be charged using memory slot 2 of the charger. The 2600 mAh 2-cell Lipos can be charged using memory slot 3 for fast charging and memory slot 4 for slower charging (use this if the battery gets run really low for 10-20 minutes then switch to fast charging). The 2600 mAh 4-cell Lipo can be charged using memory slot 8. The 1600 mAh 2-cell and 2600 mAr 4-cell generally charge in 10-20 minutes apiece while I generally fine it takes the 2600 mAh 2-cell up to 70 minutes to charge fully.
=== Setting up the camera system ===
The camera system is run on the windows computer CO3050-07. You can log into this computer using a local microcart username and password which is not posted here for security reasons but any one who works in the lab should know it. Once logged in look for Tracking Tools in the start menu or look for the shortcut shown below:
[[Image:TrackingTools_shortcut.PNG|thumb|center|Tracking Tools shortcut]]
Once the program opens the screen should look something like this:
[[Image:NewTrackingTools.PNG|800px]]
In the Tracking Tools Quick Start pop up menu select Open Existing Project and then navigate to D:\Optitrack_Configuration (It should open to this directory by default) and select the most recent Tracking Tools project. It should be named like TrackingToolsProject YYYY-MM-DD timeStamp.ttp. This is normally the most recently edited file when sorting by data modified. The most recent one as of August 1st, 2016 is TrackingToolsProject 2015-09-23 2.30pm.ttp.
[[Image:OpeningProject.PNG|800px]]
You should notice that the cameras shown in main project scree arrange themselves like out camera configuration once the project has been opened. Now the constellations need to be loaded. This can be done by going to File->Open and another pop up window will open. Navigate back to D:\Optitrack_Configuration (It should open to this directory by default) and select the most recently dated set of RADA trackables. They are named like RADA_entireSystem_M_D_YYYY.tra. The most recent one as of August 1st, 2016 is RADA_entireSystem_7_8_2016.tra.
[[Image:Opening_trackables.PNG|800px]]
Once the project and trackless are open the cameras should appear in their constellation (square) and there should be two constellations under Project Explorer->Trackables. One Named UAV for the pendulum and one named ERIS for the ground vehicle. In order to get additional information about each constellation left click on the the name of the desired trackable.
[[Image:SelectingUAV.PNG|800px]]
Once a trackable is selected more information about it is available in the Trackables Tab on the right side of the screen. For the current position and orientation look at the Real-Time Info sub -tab. This gives the orientation in the wrong order for how we currently use the Euler angles. When two or three of the angles are near zero you can switch yaw and pitch to get roughly the correct orientation.
[[Image:Uav_realTimeInfo.PNG|800px]]
Now we need check to make sure the system is zeroed.
1. Hold RADA so that the front of the ground robot (ERIS is facing the wall with the white boards (east)). The front side of Eris is labeled. If it isn't it is the side opposite of the switches and the side with the trackable constellation on it.
2. Make sure that the motor with the red motor mount is also facing the wall with the white boards.
3. Make sure the quad system is aligned along Eris Axis by standing behind the system and seeing if you can use the pole to block mounting bolts of the front propeller motor mount when looking at the pole while facing the east wall.
4. While holding the pendulum approximately vertical see if the camera system reads zeros for the pendulum (UAV) pitch and roll (yaw and roll in Real-Time Info). If yaw is off by a few degrees that is fine.
5. Compare the yaw of the UAV to that of ERIS (Remember this is pitch in REal-Time Info). If they are both near zero and with in a few degrees and the pendulum's pitch/roll were also near zero then you are ready to use the camera system. Otherwise go to the next step.
6. You need to zero the pendulum.
- Align ERIS so it is near zero yaw first (eye ball it).
- Get a level and a friend. Have your friend use a level to ensure that the pendulum is level in both directs and hold it there.
- With the UAV constellation selected go to the Orientation tab (next to Real-Time Info tab) and click on Reset To Current Orientation button
- Now your friend can set the pendulum down and you can zero ERIS the same way.
7. Save the new trackable orientation by going to File->Save Trakables... and save a file using the same naming conventions as the trackable file you opened earlier except use the current data so you don't have to re-zero the system the next time you test.
[[Image:Uav_ResetOrientation.PNG|800px]]
=== Building Software ===
=== Turing on RADA ===
=== Connecting to RADA ===
== Testing RADA ==
=== Running the first test after power up ===
=== Running additional tests ===
=== Measuring battery voltages ===
=== Locating and retrieving log files ===
== Post processing and Simulation ==
=== Using the MATLAB data parsing tool ===
=== Adding additional data for simulations ===
=== Setting up the MATLAB workspace for simulation ===
=== Running simulations and storing results ===
=== Plotting results ===
7b32d171d4ffdd540e8b59304bd44d61acb4a6cd
204
203
2016-08-02T00:37:03Z
Pfuhing
5
wikitext
text/x-wiki
This page will take you though setting up and testing RADA, retrieving the log file and other necessary data to run a simulation of that test and processing the data in MATLAB. Then actually running the simulation of RADA in Simulink.
== Setting Up a RADA Test ==
Testing RADA is not overly difficult once you get the hang of the steps to setup RADA. The following steps may seem like a long process to go from starting the testing process to having completed simulation and plotting of the test results but this whole test procedure (with the exception of battery charging) can be completed in about 15-20 minutes. These steps are meant to be as detailed as possible in order to help new users of RADA to get up and running as quickly as possible.
'''<span style="color:red">NOTE: Always run RADA with at least 2 people!</span>''' The pendulum arm can crash into the ground if the network starts to drop packets and one person cannot give commands to RADA and spot the pendulum. This is a safety issue for both you and the RADA platform.
=== Charging batteries ===
The lab currently uses mostly Hyperion batteries. We charge our batteries with a Hyperion EOS 1420i Net3 battery charger. For some general information about how to use this charger see [https://www.youtube.com/watch?v=-ox3EpzvsJ8 this video.]. In the lab we power this charger using the old Kepco Power supplu because it is the only power supply that we have that can supply enough current. Make sure that the power supply is set to an output voltage between 10.5V-29V.
{| class="wikitable" style="text-align:center"
|-
| [[Image:ChargerPowerSupplyOff.JPG|400px]]
| [[Image:ChargerPowerSuplyOn.JPG|400px]]
|-
| Kepco Power Supply off.
| Kepco Power Supply on with correct voltage supply range.
|}
While the YouTube video linked above should explain how to use the charger. Currently three different Lithium polymer batteries (Lipo): 1600 mAh 2-cell Lipo for the wheels, 2600 mAh 2-cell Lipo for the electronics of Eris, and a 2600 mAh 4-cell Lipo. The 1600 mAh 2-cell Lipo can be charged using memory slot 2 of the charger. The 2600 mAh 2-cell Lipos can be charged using memory slot 3 for fast charging and memory slot 4 for slower charging (use this if the battery gets run really low for 10-20 minutes then switch to fast charging). The 2600 mAh 4-cell Lipo can be charged using memory slot 8. The 1600 mAh 2-cell and 2600 mAr 4-cell generally charge in 10-20 minutes apiece while I generally fine it takes the 2600 mAh 2-cell up to 70 minutes to charge fully.
=== Setting up the camera system ===
The camera system is run on the windows computer CO3050-07. You can log into this computer using a local microcart username and password which is not posted here for security reasons but any one who works in the lab should know it. Once logged in look for Tracking Tools in the start menu or look for the shortcut shown below:
[[Image:TrackingTools_shortcut.PNG|thumb|center|Tracking Tools shortcut]]
Once the program opens the screen should look something like this:
[[Image:NewTrackingTools.PNG|800px]]
In the Tracking Tools Quick Start pop up menu select Open Existing Project and then navigate to D:\Optitrack_Configuration (It should open to this directory by default) and select the most recent Tracking Tools project. It should be named like TrackingToolsProject YYYY-MM-DD timeStamp.ttp. This is normally the most recently edited file when sorting by data modified. The most recent one as of August 1st, 2016 is TrackingToolsProject 2015-09-23 2.30pm.ttp.
[[Image:OpeningProject.PNG|800px]]
You should notice that the cameras shown in main project scree arrange themselves like out camera configuration once the project has been opened. Now the constellations need to be loaded. This can be done by going to File->Open and another pop up window will open. Navigate back to D:\Optitrack_Configuration (It should open to this directory by default) and select the most recently dated set of RADA trackables. They are named like RADA_entireSystem_M_D_YYYY.tra. The most recent one as of August 1st, 2016 is RADA_entireSystem_7_8_2016.tra.
[[Image:Opening_trackables.PNG|800px]]
Once the project and trackless are open the cameras should appear in their constellation (square) and there should be two constellations under Project Explorer->Trackables. One Named UAV for the pendulum and one named ERIS for the ground vehicle. In order to get additional information about each constellation left click on the the name of the desired trackable.
[[Image:SelectingUAV.PNG|800px]]
Once a trackable is selected more information about it is available in the Trackables Tab on the right side of the screen. For the current position and orientation look at the Real-Time Info sub -tab. This gives the orientation in the wrong order for how we currently use the Euler angles. When two or three of the angles are near zero you can switch yaw and pitch to get roughly the correct orientation.
[[Image:Uav_realTimeInfo.PNG|800px]]
Now we need check to make sure the system is zeroed.
1. Hold RADA so that the front of the ground robot (ERIS is facing the wall with the white boards (east)). The front side of Eris is labeled. If it isn't it is the side opposite of the switches and the side with the trackable constellation on it.
2. Make sure that the motor with the red motor mount is also facing the wall with the white boards.
3. Make sure the quad system is aligned along Eris Axis by standing behind the system and seeing if you can use the pole to block mounting bolts of the front propeller motor mount when looking at the pole while facing the east wall.
4. While holding the pendulum approximately vertical see if the camera system reads zeros for the pendulum (UAV) pitch and roll (yaw and roll in Real-Time Info). If yaw is off by a few degrees that is fine.
5. Compare the yaw of the UAV to that of ERIS (Remember this is pitch in REal-Time Info). If they are both near zero and with in a few degrees and the pendulum's pitch/roll were also near zero then you are ready to use the camera system. Otherwise go to the next step.
6. You need to zero the pendulum.
- Align ERIS so it is near zero yaw first (eye ball it).
- Get a level and a friend. Have your friend use a level to ensure that the pendulum is level in both directs and hold it there.
- With the UAV constellation selected go to the Orientation tab (next to Real-Time Info tab) and click on Reset To Current Orientation button
- Now your friend can set the pendulum down and you can zero ERIS the same way.
7. Save the new trackable orientation by going to File->Save Trakables... and save a file using the same naming conventions as the trackable file you opened earlier except use the current data so you don't have to re-zero the system the next time you test.
[[Image:Uav_ResetOrientation.PNG|800px]]
=== Building Software ===
The development environment for running RADA is hosted on CO3050-11, a Linux Red Hat environment. This computer has a local ucart user name that you should use. The password isn't put here for security reasons. In order to ensure that the RADA software is setup correctly for the test you want
=== Turing on RADA ===
=== Connecting to RADA ===
== Testing RADA ==
=== Running the first test after power up ===
=== Running additional tests ===
=== Measuring battery voltages ===
=== Locating and retrieving log files ===
== Post processing and Simulation ==
=== Using the MATLAB data parsing tool ===
=== Adding additional data for simulations ===
=== Setting up the MATLAB workspace for simulation ===
=== Running simulations and storing results ===
=== Plotting results ===
6121a33f5e5bf00e74ebc529592af5d9586f7e11
205
204
2016-08-02T00:46:23Z
Pfuhing
5
wikitext
text/x-wiki
This page will take you though setting up and testing RADA, retrieving the log file and other necessary data to run a simulation of that test and processing the data in MATLAB. Then actually running the simulation of RADA in Simulink.
== Setting Up a RADA Test ==
Testing RADA is not overly difficult once you get the hang of the steps to setup RADA. The following steps may seem like a long process to go from starting the testing process to having completed simulation and plotting of the test results but this whole test procedure (with the exception of battery charging) can be completed in about 15-20 minutes. These steps are meant to be as detailed as possible in order to help new users of RADA to get up and running as quickly as possible.
'''<span style="color:red">NOTE: Always run RADA with at least 2 people!</span>''' The pendulum arm can crash into the ground if the network starts to drop packets and one person cannot give commands to RADA and spot the pendulum. This is a safety issue for both you and the RADA platform.
=== Charging batteries ===
The lab currently uses mostly Hyperion batteries. We charge our batteries with a Hyperion EOS 1420i Net3 battery charger. For some general information about how to use this charger see [https://www.youtube.com/watch?v=-ox3EpzvsJ8 this video.]. In the lab we power this charger using the old Kepco Power supplu because it is the only power supply that we have that can supply enough current. Make sure that the power supply is set to an output voltage between 10.5V-29V.
{| class="wikitable" style="text-align:center"
|-
| [[Image:ChargerPowerSupplyOff.JPG|400px]]
| [[Image:ChargerPowerSuplyOn.JPG|400px]]
|-
| Kepco Power Supply off.
| Kepco Power Supply on with correct voltage supply range.
|}
While the YouTube video linked above should explain how to use the charger. Currently three different Lithium polymer batteries (Lipo): 1600 mAh 2-cell Lipo for the wheels, 2600 mAh 2-cell Lipo for the electronics of Eris, and a 2600 mAh 4-cell Lipo. The 1600 mAh 2-cell Lipo can be charged using memory slot 2 of the charger. The 2600 mAh 2-cell Lipos can be charged using memory slot 3 for fast charging and memory slot 4 for slower charging (use this if the battery gets run really low for 10-20 minutes then switch to fast charging). The 2600 mAh 4-cell Lipo can be charged using memory slot 8. The 1600 mAh 2-cell and 2600 mAr 4-cell generally charge in 10-20 minutes apiece while I generally fine it takes the 2600 mAh 2-cell up to 70 minutes to charge fully.
=== Setting up the camera system ===
The camera system is run on the windows computer CO3050-07. You can log into this computer using a local microcart username and password which is not posted here for security reasons but any one who works in the lab should know it. Once logged in look for Tracking Tools in the start menu or look for the shortcut shown below:
[[Image:TrackingTools_shortcut.PNG|thumb|center|Tracking Tools shortcut]]
Once the program opens the screen should look something like this:
[[Image:NewTrackingTools.PNG|800px]]
In the Tracking Tools Quick Start pop up menu select Open Existing Project and then navigate to D:\Optitrack_Configuration (It should open to this directory by default) and select the most recent Tracking Tools project. It should be named like TrackingToolsProject YYYY-MM-DD timeStamp.ttp. This is normally the most recently edited file when sorting by data modified. The most recent one as of August 1st, 2016 is TrackingToolsProject 2015-09-23 2.30pm.ttp.
[[Image:OpeningProject.PNG|800px]]
You should notice that the cameras shown in main project scree arrange themselves like out camera configuration once the project has been opened. Now the constellations need to be loaded. This can be done by going to File->Open and another pop up window will open. Navigate back to D:\Optitrack_Configuration (It should open to this directory by default) and select the most recently dated set of RADA trackables. They are named like RADA_entireSystem_M_D_YYYY.tra. The most recent one as of August 1st, 2016 is RADA_entireSystem_7_8_2016.tra.
[[Image:Opening_trackables.PNG|800px]]
Once the project and trackless are open the cameras should appear in their constellation (square) and there should be two constellations under Project Explorer->Trackables. One Named UAV for the pendulum and one named ERIS for the ground vehicle. In order to get additional information about each constellation left click on the the name of the desired trackable.
[[Image:SelectingUAV.PNG|800px]]
Once a trackable is selected more information about it is available in the Trackables Tab on the right side of the screen. For the current position and orientation look at the Real-Time Info sub -tab. This gives the orientation in the wrong order for how we currently use the Euler angles. When two or three of the angles are near zero you can switch yaw and pitch to get roughly the correct orientation.
[[Image:Uav_realTimeInfo.PNG|800px]]
Now we need check to make sure the system is zeroed.
1. Hold RADA so that the front of the ground robot (ERIS is facing the wall with the white boards (east)). The front side of Eris is labeled. If it isn't it is the side opposite of the switches and the side with the trackable constellation on it.
2. Make sure that the motor with the red motor mount is also facing the wall with the white boards.
3. Make sure the quad system is aligned along Eris Axis by standing behind the system and seeing if you can use the pole to block mounting bolts of the front propeller motor mount when looking at the pole while facing the east wall.
4. While holding the pendulum approximately vertical see if the camera system reads zeros for the pendulum (UAV) pitch and roll (yaw and roll in Real-Time Info). If yaw is off by a few degrees that is fine.
5. Compare the yaw of the UAV to that of ERIS (Remember this is pitch in REal-Time Info). If they are both near zero and with in a few degrees and the pendulum's pitch/roll were also near zero then you are ready to use the camera system. Otherwise go to the next step.
6. You need to zero the pendulum.
- Align ERIS so it is near zero yaw first (eye ball it).
- Get a level and a friend. Have your friend use a level to ensure that the pendulum is level in both directs and hold it there.
- With the UAV constellation selected go to the Orientation tab (next to Real-Time Info tab) and click on Reset To Current Orientation button
- Now your friend can set the pendulum down and you can zero ERIS the same way.
7. Save the new trackable orientation by going to File->Save Trakables... and save a file using the same naming conventions as the trackable file you opened earlier except use the current data so you don't have to re-zero the system the next time you test.
[[Image:Uav_ResetOrientation.PNG|800px]]
=== Building Software ===
The development environment for running RADA is hosted on CO3050-11, a Linux Red Hat environment. This computer has a local ucart user name that you should use. The password isn't put here for security reasons. In order to ensure that the RADA software is setup correctly for the test you want to run. To do this you will need to open the main.cpp and logger.cpp files and make sure all of the compile time macros you want are defined correctly. All of the c++ files you should need to edit are in the directory ~/Desktop/rada_research_project/ErisResearchCode/CppProjects/MainProgram_PacketLoss/src/Korebot Below is a compiler macro options for main.cpp:
=== Turing on RADA ===
=== Connecting to RADA ===
== Testing RADA ==
=== Running the first test after power up ===
=== Running additional tests ===
=== Measuring battery voltages ===
=== Locating and retrieving log files ===
== Post processing and Simulation ==
=== Using the MATLAB data parsing tool ===
=== Adding additional data for simulations ===
=== Setting up the MATLAB workspace for simulation ===
=== Running simulations and storing results ===
=== Plotting results ===
675443722497f710124ee0ea08f0e223acbf5a89
206
205
2016-08-02T00:56:59Z
Pfuhing
5
wikitext
text/x-wiki
This page will take you though setting up and testing RADA, retrieving the log file and other necessary data to run a simulation of that test and processing the data in MATLAB. Then actually running the simulation of RADA in Simulink.
== Setting Up a RADA Test ==
Testing RADA is not overly difficult once you get the hang of the steps to setup RADA. The following steps may seem like a long process to go from starting the testing process to having completed simulation and plotting of the test results but this whole test procedure (with the exception of battery charging) can be completed in about 15-20 minutes. These steps are meant to be as detailed as possible in order to help new users of RADA to get up and running as quickly as possible.
'''<span style="color:red">NOTE: Always run RADA with at least 2 people!</span>''' The pendulum arm can crash into the ground if the network starts to drop packets and one person cannot give commands to RADA and spot the pendulum. This is a safety issue for both you and the RADA platform.
=== Charging batteries ===
The lab currently uses mostly Hyperion batteries. We charge our batteries with a Hyperion EOS 1420i Net3 battery charger. For some general information about how to use this charger see [https://www.youtube.com/watch?v=-ox3EpzvsJ8 this video.]. In the lab we power this charger using the old Kepco Power supplu because it is the only power supply that we have that can supply enough current. Make sure that the power supply is set to an output voltage between 10.5V-29V.
{| class="wikitable" style="text-align:center"
|-
| [[Image:ChargerPowerSupplyOff.JPG|400px]]
| [[Image:ChargerPowerSuplyOn.JPG|400px]]
|-
| Kepco Power Supply off.
| Kepco Power Supply on with correct voltage supply range.
|}
While the YouTube video linked above should explain how to use the charger. Currently three different Lithium polymer batteries (Lipo): 1600 mAh 2-cell Lipo for the wheels, 2600 mAh 2-cell Lipo for the electronics of Eris, and a 2600 mAh 4-cell Lipo. The 1600 mAh 2-cell Lipo can be charged using memory slot 2 of the charger. The 2600 mAh 2-cell Lipos can be charged using memory slot 3 for fast charging and memory slot 4 for slower charging (use this if the battery gets run really low for 10-20 minutes then switch to fast charging). The 2600 mAh 4-cell Lipo can be charged using memory slot 8. The 1600 mAh 2-cell and 2600 mAr 4-cell generally charge in 10-20 minutes apiece while I generally fine it takes the 2600 mAh 2-cell up to 70 minutes to charge fully.
=== Setting up the camera system ===
The camera system is run on the windows computer CO3050-07. You can log into this computer using a local microcart username and password which is not posted here for security reasons but any one who works in the lab should know it. Once logged in look for Tracking Tools in the start menu or look for the shortcut shown below:
[[Image:TrackingTools_shortcut.PNG|thumb|center|Tracking Tools shortcut]]
Once the program opens the screen should look something like this:
[[Image:NewTrackingTools.PNG|800px]]
In the Tracking Tools Quick Start pop up menu select Open Existing Project and then navigate to D:\Optitrack_Configuration (It should open to this directory by default) and select the most recent Tracking Tools project. It should be named like TrackingToolsProject YYYY-MM-DD timeStamp.ttp. This is normally the most recently edited file when sorting by data modified. The most recent one as of August 1st, 2016 is TrackingToolsProject 2015-09-23 2.30pm.ttp.
[[Image:OpeningProject.PNG|800px]]
You should notice that the cameras shown in main project scree arrange themselves like out camera configuration once the project has been opened. Now the constellations need to be loaded. This can be done by going to File->Open and another pop up window will open. Navigate back to D:\Optitrack_Configuration (It should open to this directory by default) and select the most recently dated set of RADA trackables. They are named like RADA_entireSystem_M_D_YYYY.tra. The most recent one as of August 1st, 2016 is RADA_entireSystem_7_8_2016.tra.
[[Image:Opening_trackables.PNG|800px]]
Once the project and trackless are open the cameras should appear in their constellation (square) and there should be two constellations under Project Explorer->Trackables. One Named UAV for the pendulum and one named ERIS for the ground vehicle. In order to get additional information about each constellation left click on the the name of the desired trackable.
[[Image:SelectingUAV.PNG|800px]]
Once a trackable is selected more information about it is available in the Trackables Tab on the right side of the screen. For the current position and orientation look at the Real-Time Info sub -tab. This gives the orientation in the wrong order for how we currently use the Euler angles. When two or three of the angles are near zero you can switch yaw and pitch to get roughly the correct orientation.
[[Image:Uav_realTimeInfo.PNG|800px]]
Now we need check to make sure the system is zeroed.
1. Hold RADA so that the front of the ground robot (ERIS is facing the wall with the white boards (east)). The front side of Eris is labeled. If it isn't it is the side opposite of the switches and the side with the trackable constellation on it.
2. Make sure that the motor with the red motor mount is also facing the wall with the white boards.
3. Make sure the quad system is aligned along Eris Axis by standing behind the system and seeing if you can use the pole to block mounting bolts of the front propeller motor mount when looking at the pole while facing the east wall.
4. While holding the pendulum approximately vertical see if the camera system reads zeros for the pendulum (UAV) pitch and roll (yaw and roll in Real-Time Info). If yaw is off by a few degrees that is fine.
5. Compare the yaw of the UAV to that of ERIS (Remember this is pitch in REal-Time Info). If they are both near zero and with in a few degrees and the pendulum's pitch/roll were also near zero then you are ready to use the camera system. Otherwise go to the next step.
6. You need to zero the pendulum.
- Align ERIS so it is near zero yaw first (eye ball it).
- Get a level and a friend. Have your friend use a level to ensure that the pendulum is level in both directs and hold it there.
- With the UAV constellation selected go to the Orientation tab (next to Real-Time Info tab) and click on Reset To Current Orientation button
- Now your friend can set the pendulum down and you can zero ERIS the same way.
7. Save the new trackable orientation by going to File->Save Trakables... and save a file using the same naming conventions as the trackable file you opened earlier except use the current data so you don't have to re-zero the system the next time you test.
[[Image:Uav_ResetOrientation.PNG|800px]]
=== Building Software ===
The development environment for running RADA is hosted on CO3050-11, a Linux Red Hat environment. This computer has a local ucart user name that you should use. The password isn't put here for security reasons. In order to ensure that the RADA software is setup correctly for the test you want to run. To do this you will need to open the main.cpp and logger.cpp files and make sure all of the compile time macros you want are defined correctly. All of the c++ files you should need to edit are in the directory ~/Desktop/rada_research_project/ErisResearchCode/CppProjects/MainProgram_PacketLoss/src/Korebot Below is a compiler macro options for main.cpp:
*'''H2ctrl''' : This will cause the system to enter H2 controller mode where the whole RADA system is controlled by an H2 controller.
*'''ssTracking''' : H2ctrl must also be defined for this macro to do anything. This macro will has the system to be controlled by a tracking H2 controller.
*'''ssMotors''' : H2ctrl must also be defined for this macro to do anything. This macro will has the system to be controlled by an H2 contorller that contains propeller states. This also cause the system to "Dance."
*'''ssDrop''' : Cause the system to go into packet drop controller mode. This mode allows controllers designed for lossy networks to be tested. Based off of other definitions how lossy the network is can be simulated.
*drop10
*drop30
*drop50
*mot50
*RADAlqi
*RADAlqi_est
*rada_lqg
*rada_split_lqg
*rada_split_lqg_ol
*yaw_off
*accR
*posRamp
=== Turing on RADA ===
=== Connecting to RADA ===
== Testing RADA ==
=== Running the first test after power up ===
=== Running additional tests ===
=== Measuring battery voltages ===
=== Locating and retrieving log files ===
== Post processing and Simulation ==
=== Using the MATLAB data parsing tool ===
=== Adding additional data for simulations ===
=== Setting up the MATLAB workspace for simulation ===
=== Running simulations and storing results ===
=== Plotting results ===
754c52a78c73b04d4b5e0991feebc3e5c410ded6
207
206
2016-08-02T00:59:55Z
Pfuhing
5
wikitext
text/x-wiki
This page will take you though setting up and testing RADA, retrieving the log file and other necessary data to run a simulation of that test and processing the data in MATLAB. Then actually running the simulation of RADA in Simulink.
== Setting Up a RADA Test ==
Testing RADA is not overly difficult once you get the hang of the steps to setup RADA. The following steps may seem like a long process to go from starting the testing process to having completed simulation and plotting of the test results but this whole test procedure (with the exception of battery charging) can be completed in about 15-20 minutes. These steps are meant to be as detailed as possible in order to help new users of RADA to get up and running as quickly as possible.
'''<span style="color:red">NOTE: Always run RADA with at least 2 people!</span>''' The pendulum arm can crash into the ground if the network starts to drop packets and one person cannot give commands to RADA and spot the pendulum. This is a safety issue for both you and the RADA platform.
=== Charging batteries ===
The lab currently uses mostly Hyperion batteries. We charge our batteries with a Hyperion EOS 1420i Net3 battery charger. For some general information about how to use this charger see [https://www.youtube.com/watch?v=-ox3EpzvsJ8 this video.]. In the lab we power this charger using the old Kepco Power supplu because it is the only power supply that we have that can supply enough current. Make sure that the power supply is set to an output voltage between 10.5V-29V.
{| class="wikitable" style="text-align:center"
|-
| [[Image:ChargerPowerSupplyOff.JPG|400px]]
| [[Image:ChargerPowerSuplyOn.JPG|400px]]
|-
| Kepco Power Supply off.
| Kepco Power Supply on with correct voltage supply range.
|}
While the YouTube video linked above should explain how to use the charger. Currently three different Lithium polymer batteries (Lipo): 1600 mAh 2-cell Lipo for the wheels, 2600 mAh 2-cell Lipo for the electronics of Eris, and a 2600 mAh 4-cell Lipo. The 1600 mAh 2-cell Lipo can be charged using memory slot 2 of the charger. The 2600 mAh 2-cell Lipos can be charged using memory slot 3 for fast charging and memory slot 4 for slower charging (use this if the battery gets run really low for 10-20 minutes then switch to fast charging). The 2600 mAh 4-cell Lipo can be charged using memory slot 8. The 1600 mAh 2-cell and 2600 mAr 4-cell generally charge in 10-20 minutes apiece while I generally fine it takes the 2600 mAh 2-cell up to 70 minutes to charge fully.
=== Setting up the camera system ===
The camera system is run on the windows computer CO3050-07. You can log into this computer using a local microcart username and password which is not posted here for security reasons but any one who works in the lab should know it. Once logged in look for Tracking Tools in the start menu or look for the shortcut shown below:
[[Image:TrackingTools_shortcut.PNG|thumb|center|Tracking Tools shortcut]]
Once the program opens the screen should look something like this:
[[Image:NewTrackingTools.PNG|800px]]
In the Tracking Tools Quick Start pop up menu select Open Existing Project and then navigate to D:\Optitrack_Configuration (It should open to this directory by default) and select the most recent Tracking Tools project. It should be named like TrackingToolsProject YYYY-MM-DD timeStamp.ttp. This is normally the most recently edited file when sorting by data modified. The most recent one as of August 1st, 2016 is TrackingToolsProject 2015-09-23 2.30pm.ttp.
[[Image:OpeningProject.PNG|800px]]
You should notice that the cameras shown in main project scree arrange themselves like out camera configuration once the project has been opened. Now the constellations need to be loaded. This can be done by going to File->Open and another pop up window will open. Navigate back to D:\Optitrack_Configuration (It should open to this directory by default) and select the most recently dated set of RADA trackables. They are named like RADA_entireSystem_M_D_YYYY.tra. The most recent one as of August 1st, 2016 is RADA_entireSystem_7_8_2016.tra.
[[Image:Opening_trackables.PNG|800px]]
Once the project and trackless are open the cameras should appear in their constellation (square) and there should be two constellations under Project Explorer->Trackables. One Named UAV for the pendulum and one named ERIS for the ground vehicle. In order to get additional information about each constellation left click on the the name of the desired trackable.
[[Image:SelectingUAV.PNG|800px]]
Once a trackable is selected more information about it is available in the Trackables Tab on the right side of the screen. For the current position and orientation look at the Real-Time Info sub -tab. This gives the orientation in the wrong order for how we currently use the Euler angles. When two or three of the angles are near zero you can switch yaw and pitch to get roughly the correct orientation.
[[Image:Uav_realTimeInfo.PNG|800px]]
Now we need check to make sure the system is zeroed.
1. Hold RADA so that the front of the ground robot (ERIS is facing the wall with the white boards (east)). The front side of Eris is labeled. If it isn't it is the side opposite of the switches and the side with the trackable constellation on it.
2. Make sure that the motor with the red motor mount is also facing the wall with the white boards.
3. Make sure the quad system is aligned along Eris Axis by standing behind the system and seeing if you can use the pole to block mounting bolts of the front propeller motor mount when looking at the pole while facing the east wall.
4. While holding the pendulum approximately vertical see if the camera system reads zeros for the pendulum (UAV) pitch and roll (yaw and roll in Real-Time Info). If yaw is off by a few degrees that is fine.
5. Compare the yaw of the UAV to that of ERIS (Remember this is pitch in REal-Time Info). If they are both near zero and with in a few degrees and the pendulum's pitch/roll were also near zero then you are ready to use the camera system. Otherwise go to the next step.
6. You need to zero the pendulum.
- Align ERIS so it is near zero yaw first (eye ball it).
- Get a level and a friend. Have your friend use a level to ensure that the pendulum is level in both directs and hold it there.
- With the UAV constellation selected go to the Orientation tab (next to Real-Time Info tab) and click on Reset To Current Orientation button
- Now your friend can set the pendulum down and you can zero ERIS the same way.
7. Save the new trackable orientation by going to File->Save Trakables... and save a file using the same naming conventions as the trackable file you opened earlier except use the current data so you don't have to re-zero the system the next time you test.
[[Image:Uav_ResetOrientation.PNG|800px]]
=== Building Software ===
The development environment for running RADA is hosted on CO3050-11, a Linux Red Hat environment. This computer has a local ucart user name that you should use. The password isn't put here for security reasons. In order to ensure that the RADA software is setup correctly for the test you want to run. To do this you will need to open the main.cpp and logger.cpp files and make sure all of the compile time macros you want are defined correctly. All of the c++ files you should need to edit are in the directory ~/Desktop/rada_research_project/ErisResearchCode/CppProjects/MainProgram_PacketLoss/src/Korebot Below is a compiler macro options for main.cpp:
*'''H2ctrl''' : This will cause the system to enter H2 controller mode where the whole RADA system is controlled by an H2 controller.
*'''ssTracking''' : H2ctrl must also be defined for this macro to do anything. This macro will has the system to be controlled by a tracking H2 controller.
*'''ssMotors''' : H2ctrl must also be defined for this macro to do anything. This macro will has the system to be controlled by an H2 contorller that contains propeller states. This also cause the system to "Dance."
*'''ssDrop''' : Cause the system to go into packet drop controller mode. This mode allows controllers designed for lossy networks to be tested. Based off of other definitions how lossy the network is can be simulated. If nothing else is defined this controller becomes basically a H2 controller.
*'''drop10''' : Will put the packet drop mode into 10% loss mode and use a controller designed for 10% loss.
*'''drop30''' : Will put the packet drop mode into 30% loss mode and use a controller designed for 30% loss.
*'''drop50''' : Will put the packet drop mode into 50% loss mode and use a controller designed for 50% loss.
*mot50
*RADAlqi
*RADAlqi_est
*rada_lqg
*rada_split_lqg
*rada_split_lqg_ol
*yaw_off
*accR
*posRamp
=== Turing on RADA ===
=== Connecting to RADA ===
== Testing RADA ==
=== Running the first test after power up ===
=== Running additional tests ===
=== Measuring battery voltages ===
=== Locating and retrieving log files ===
== Post processing and Simulation ==
=== Using the MATLAB data parsing tool ===
=== Adding additional data for simulations ===
=== Setting up the MATLAB workspace for simulation ===
=== Running simulations and storing results ===
=== Plotting results ===
8943e83fdea6e821a7046d2a4e7da2cde7acf9bc
208
207
2016-08-02T01:03:48Z
Pfuhing
5
wikitext
text/x-wiki
This page will take you though setting up and testing RADA, retrieving the log file and other necessary data to run a simulation of that test and processing the data in MATLAB. Then actually running the simulation of RADA in Simulink.
== Setting Up a RADA Test ==
Testing RADA is not overly difficult once you get the hang of the steps to setup RADA. The following steps may seem like a long process to go from starting the testing process to having completed simulation and plotting of the test results but this whole test procedure (with the exception of battery charging) can be completed in about 15-20 minutes. These steps are meant to be as detailed as possible in order to help new users of RADA to get up and running as quickly as possible.
'''<span style="color:red">NOTE: Always run RADA with at least 2 people!</span>''' The pendulum arm can crash into the ground if the network starts to drop packets and one person cannot give commands to RADA and spot the pendulum. This is a safety issue for both you and the RADA platform.
=== Charging batteries ===
The lab currently uses mostly Hyperion batteries. We charge our batteries with a Hyperion EOS 1420i Net3 battery charger. For some general information about how to use this charger see [https://www.youtube.com/watch?v=-ox3EpzvsJ8 this video.]. In the lab we power this charger using the old Kepco Power supplu because it is the only power supply that we have that can supply enough current. Make sure that the power supply is set to an output voltage between 10.5V-29V.
{| class="wikitable" style="text-align:center"
|-
| [[Image:ChargerPowerSupplyOff.JPG|400px]]
| [[Image:ChargerPowerSuplyOn.JPG|400px]]
|-
| Kepco Power Supply off.
| Kepco Power Supply on with correct voltage supply range.
|}
While the YouTube video linked above should explain how to use the charger. Currently three different Lithium polymer batteries (Lipo): 1600 mAh 2-cell Lipo for the wheels, 2600 mAh 2-cell Lipo for the electronics of Eris, and a 2600 mAh 4-cell Lipo. The 1600 mAh 2-cell Lipo can be charged using memory slot 2 of the charger. The 2600 mAh 2-cell Lipos can be charged using memory slot 3 for fast charging and memory slot 4 for slower charging (use this if the battery gets run really low for 10-20 minutes then switch to fast charging). The 2600 mAh 4-cell Lipo can be charged using memory slot 8. The 1600 mAh 2-cell and 2600 mAr 4-cell generally charge in 10-20 minutes apiece while I generally fine it takes the 2600 mAh 2-cell up to 70 minutes to charge fully.
=== Setting up the camera system ===
The camera system is run on the windows computer CO3050-07. You can log into this computer using a local microcart username and password which is not posted here for security reasons but any one who works in the lab should know it. Once logged in look for Tracking Tools in the start menu or look for the shortcut shown below:
[[Image:TrackingTools_shortcut.PNG|thumb|center|Tracking Tools shortcut]]
Once the program opens the screen should look something like this:
[[Image:NewTrackingTools.PNG|800px]]
In the Tracking Tools Quick Start pop up menu select Open Existing Project and then navigate to D:\Optitrack_Configuration (It should open to this directory by default) and select the most recent Tracking Tools project. It should be named like TrackingToolsProject YYYY-MM-DD timeStamp.ttp. This is normally the most recently edited file when sorting by data modified. The most recent one as of August 1st, 2016 is TrackingToolsProject 2015-09-23 2.30pm.ttp.
[[Image:OpeningProject.PNG|800px]]
You should notice that the cameras shown in main project scree arrange themselves like out camera configuration once the project has been opened. Now the constellations need to be loaded. This can be done by going to File->Open and another pop up window will open. Navigate back to D:\Optitrack_Configuration (It should open to this directory by default) and select the most recently dated set of RADA trackables. They are named like RADA_entireSystem_M_D_YYYY.tra. The most recent one as of August 1st, 2016 is RADA_entireSystem_7_8_2016.tra.
[[Image:Opening_trackables.PNG|800px]]
Once the project and trackless are open the cameras should appear in their constellation (square) and there should be two constellations under Project Explorer->Trackables. One Named UAV for the pendulum and one named ERIS for the ground vehicle. In order to get additional information about each constellation left click on the the name of the desired trackable.
[[Image:SelectingUAV.PNG|800px]]
Once a trackable is selected more information about it is available in the Trackables Tab on the right side of the screen. For the current position and orientation look at the Real-Time Info sub -tab. This gives the orientation in the wrong order for how we currently use the Euler angles. When two or three of the angles are near zero you can switch yaw and pitch to get roughly the correct orientation.
[[Image:Uav_realTimeInfo.PNG|800px]]
Now we need check to make sure the system is zeroed.
1. Hold RADA so that the front of the ground robot (ERIS is facing the wall with the white boards (east)). The front side of Eris is labeled. If it isn't it is the side opposite of the switches and the side with the trackable constellation on it.
2. Make sure that the motor with the red motor mount is also facing the wall with the white boards.
3. Make sure the quad system is aligned along Eris Axis by standing behind the system and seeing if you can use the pole to block mounting bolts of the front propeller motor mount when looking at the pole while facing the east wall.
4. While holding the pendulum approximately vertical see if the camera system reads zeros for the pendulum (UAV) pitch and roll (yaw and roll in Real-Time Info). If yaw is off by a few degrees that is fine.
5. Compare the yaw of the UAV to that of ERIS (Remember this is pitch in REal-Time Info). If they are both near zero and with in a few degrees and the pendulum's pitch/roll were also near zero then you are ready to use the camera system. Otherwise go to the next step.
6. You need to zero the pendulum.
- Align ERIS so it is near zero yaw first (eye ball it).
- Get a level and a friend. Have your friend use a level to ensure that the pendulum is level in both directs and hold it there.
- With the UAV constellation selected go to the Orientation tab (next to Real-Time Info tab) and click on Reset To Current Orientation button
- Now your friend can set the pendulum down and you can zero ERIS the same way.
7. Save the new trackable orientation by going to File->Save Trakables... and save a file using the same naming conventions as the trackable file you opened earlier except use the current data so you don't have to re-zero the system the next time you test.
[[Image:Uav_ResetOrientation.PNG|800px]]
=== Building Software ===
The development environment for running RADA is hosted on CO3050-11, a Linux Red Hat environment. This computer has a local ucart user name that you should use. The password isn't put here for security reasons. In order to ensure that the RADA software is setup correctly for the test you want to run. To do this you will need to open the main.cpp and logger.cpp files and make sure all of the compile time macros you want are defined correctly. All of the c++ files you should need to edit are in the directory ~/Desktop/rada_research_project/ErisResearchCode/CppProjects/MainProgram_PacketLoss/src/Korebot Below is a compiler macro options for main.cpp:
*'''H2ctrl''' : This will cause the system to enter H2 controller mode where the whole RADA system is controlled by an H2 controller.
*'''ssTracking''' : H2ctrl must also be defined for this macro to do anything. This macro will has the system to be controlled by a tracking H2 controller.
*'''ssMotors''' : H2ctrl must also be defined for this macro to do anything. This macro will has the system to be controlled by an H2 contorller that contains propeller states. This also cause the system to "Dance."
*'''ssDrop''' : Cause the system to go into packet drop controller mode. This mode allows controllers designed for lossy networks to be tested. Based off of other definitions how lossy the network is can be simulated. If nothing else is defined this controller becomes basically a H2 controller.
*'''drop10''' : Will put the packet drop mode into 10% loss mode and use a controller designed for 10% loss.
*'''drop30''' : Will put the packet drop mode into 30% loss mode and use a controller designed for 30% loss.
*'''drop50''' : Will put the packet drop mode into 50% loss mode and use a controller designed for 50% loss.
*'''mot50''' : This macro over-rides all other macros. If this is turned on the wheels will not run and the propllers will be run at 50% command. This is used for measuring the effective battery voltage seen by the ESCs. This is always run after a test.
*'''RADAlqi''' : This macro will cause the system to use an LQI controller on the whole system. The linear velocity states are calculated with no filter and the angular velocity states are calculated with filters.
*'''RADAlqi_est''' : This macro will cause the system to use an LQI controller on the whole system. A traditional estimator is used to estimate the states.
*rada_lqg
*rada_split_lqg
*rada_split_lqg_ol
*yaw_off
*accR
*posRamp
=== Turing on RADA ===
=== Connecting to RADA ===
== Testing RADA ==
=== Running the first test after power up ===
=== Running additional tests ===
=== Measuring battery voltages ===
=== Locating and retrieving log files ===
== Post processing and Simulation ==
=== Using the MATLAB data parsing tool ===
=== Adding additional data for simulations ===
=== Setting up the MATLAB workspace for simulation ===
=== Running simulations and storing results ===
=== Plotting results ===
22b1ef9f98a08da0307056859ebc0ea4d62fff8d
209
208
2016-08-02T01:25:23Z
Pfuhing
5
wikitext
text/x-wiki
This page will take you though setting up and testing RADA, retrieving the log file and other necessary data to run a simulation of that test and processing the data in MATLAB. Then actually running the simulation of RADA in Simulink.
== Setting Up a RADA Test ==
Testing RADA is not overly difficult once you get the hang of the steps to setup RADA. The following steps may seem like a long process to go from starting the testing process to having completed simulation and plotting of the test results but this whole test procedure (with the exception of battery charging) can be completed in about 15-20 minutes. These steps are meant to be as detailed as possible in order to help new users of RADA to get up and running as quickly as possible.
'''<span style="color:red">NOTE: Always run RADA with at least 2 people!</span>''' The pendulum arm can crash into the ground if the network starts to drop packets and one person cannot give commands to RADA and spot the pendulum. This is a safety issue for both you and the RADA platform.
=== Charging batteries ===
The lab currently uses mostly Hyperion batteries. We charge our batteries with a Hyperion EOS 1420i Net3 battery charger. For some general information about how to use this charger see [https://www.youtube.com/watch?v=-ox3EpzvsJ8 this video.]. In the lab we power this charger using the old Kepco Power supplu because it is the only power supply that we have that can supply enough current. Make sure that the power supply is set to an output voltage between 10.5V-29V.
{| class="wikitable" style="text-align:center"
|-
| [[Image:ChargerPowerSupplyOff.JPG|400px]]
| [[Image:ChargerPowerSuplyOn.JPG|400px]]
|-
| Kepco Power Supply off.
| Kepco Power Supply on with correct voltage supply range.
|}
While the YouTube video linked above should explain how to use the charger. Currently three different Lithium polymer batteries (Lipo): 1600 mAh 2-cell Lipo for the wheels, 2600 mAh 2-cell Lipo for the electronics of Eris, and a 2600 mAh 4-cell Lipo. The 1600 mAh 2-cell Lipo can be charged using memory slot 2 of the charger. The 2600 mAh 2-cell Lipos can be charged using memory slot 3 for fast charging and memory slot 4 for slower charging (use this if the battery gets run really low for 10-20 minutes then switch to fast charging). The 2600 mAh 4-cell Lipo can be charged using memory slot 8. The 1600 mAh 2-cell and 2600 mAr 4-cell generally charge in 10-20 minutes apiece while I generally fine it takes the 2600 mAh 2-cell up to 70 minutes to charge fully.
=== Setting up the camera system ===
The camera system is run on the windows computer CO3050-07. You can log into this computer using a local microcart username and password which is not posted here for security reasons but any one who works in the lab should know it. Once logged in look for Tracking Tools in the start menu or look for the shortcut shown below:
[[Image:TrackingTools_shortcut.PNG|thumb|center|Tracking Tools shortcut]]
Once the program opens the screen should look something like this:
[[Image:NewTrackingTools.PNG|800px]]
In the Tracking Tools Quick Start pop up menu select Open Existing Project and then navigate to D:\Optitrack_Configuration (It should open to this directory by default) and select the most recent Tracking Tools project. It should be named like TrackingToolsProject YYYY-MM-DD timeStamp.ttp. This is normally the most recently edited file when sorting by data modified. The most recent one as of August 1st, 2016 is TrackingToolsProject 2015-09-23 2.30pm.ttp.
[[Image:OpeningProject.PNG|800px]]
You should notice that the cameras shown in main project scree arrange themselves like out camera configuration once the project has been opened. Now the constellations need to be loaded. This can be done by going to File->Open and another pop up window will open. Navigate back to D:\Optitrack_Configuration (It should open to this directory by default) and select the most recently dated set of RADA trackables. They are named like RADA_entireSystem_M_D_YYYY.tra. The most recent one as of August 1st, 2016 is RADA_entireSystem_7_8_2016.tra.
[[Image:Opening_trackables.PNG|800px]]
Once the project and trackless are open the cameras should appear in their constellation (square) and there should be two constellations under Project Explorer->Trackables. One Named UAV for the pendulum and one named ERIS for the ground vehicle. In order to get additional information about each constellation left click on the the name of the desired trackable.
[[Image:SelectingUAV.PNG|800px]]
Once a trackable is selected more information about it is available in the Trackables Tab on the right side of the screen. For the current position and orientation look at the Real-Time Info sub -tab. This gives the orientation in the wrong order for how we currently use the Euler angles. When two or three of the angles are near zero you can switch yaw and pitch to get roughly the correct orientation.
[[Image:Uav_realTimeInfo.PNG|800px]]
Now we need check to make sure the system is zeroed.
1. Hold RADA so that the front of the ground robot (ERIS is facing the wall with the white boards (east)). The front side of Eris is labeled. If it isn't it is the side opposite of the switches and the side with the trackable constellation on it.
2. Make sure that the motor with the red motor mount is also facing the wall with the white boards.
3. Make sure the quad system is aligned along Eris Axis by standing behind the system and seeing if you can use the pole to block mounting bolts of the front propeller motor mount when looking at the pole while facing the east wall.
4. While holding the pendulum approximately vertical see if the camera system reads zeros for the pendulum (UAV) pitch and roll (yaw and roll in Real-Time Info). If yaw is off by a few degrees that is fine.
5. Compare the yaw of the UAV to that of ERIS (Remember this is pitch in REal-Time Info). If they are both near zero and with in a few degrees and the pendulum's pitch/roll were also near zero then you are ready to use the camera system. Otherwise go to the next step.
6. You need to zero the pendulum.
- Align ERIS so it is near zero yaw first (eye ball it).
- Get a level and a friend. Have your friend use a level to ensure that the pendulum is level in both directs and hold it there.
- With the UAV constellation selected go to the Orientation tab (next to Real-Time Info tab) and click on Reset To Current Orientation button
- Now your friend can set the pendulum down and you can zero ERIS the same way.
7. Save the new trackable orientation by going to File->Save Trakables... and save a file using the same naming conventions as the trackable file you opened earlier except use the current data so you don't have to re-zero the system the next time you test.
[[Image:Uav_ResetOrientation.PNG|800px]]
=== Building Software ===
The development environment for running RADA is hosted on CO3050-11, a Linux Red Hat environment. This computer has a local ucart user name that you should use. The password isn't put here for security reasons. In order to ensure that the RADA software is setup correctly for the test you want to run. To do this you will need to open the main.cpp and logger.cpp files and make sure all of the compile time macros you want are defined correctly. All of the c++ files you should need to edit are in the directory ~/Desktop/rada_research_project/ErisResearchCode/CppProjects/MainProgram_PacketLoss/src/Korebot Below is a compiler macro options for main.cpp:
*'''H2ctrl''' : This will cause the system to enter H2 controller mode where the whole RADA system is controlled by an H2 controller.
*'''ssTracking''' : H2ctrl must also be defined for this macro to do anything. This macro will has the system to be controlled by a tracking H2 controller.
*'''ssMotors''' : H2ctrl must also be defined for this macro to do anything. This macro will has the system to be controlled by an H2 contorller that contains propeller states. This also cause the system to "Dance."
*'''ssDrop''' : Cause the system to go into packet drop controller mode. This mode allows controllers designed for lossy networks to be tested. Based off of other definitions how lossy the network is can be simulated. If nothing else is defined this controller becomes basically a H2 controller.
*'''drop10''' : Will put the packet drop mode into 10% loss mode and use a controller designed for 10% loss.
*'''drop30''' : Will put the packet drop mode into 30% loss mode and use a controller designed for 30% loss.
*'''drop50''' : Will put the packet drop mode into 50% loss mode and use a controller designed for 50% loss.
*'''mot50''' : This macro over-rides all other macros. If this is turned on the wheels will not run and the propllers will be run at 50% command. This is used for measuring the effective battery voltage seen by the ESCs. This is always run after a test.
*'''RADAlqi''' : This macro will cause the system to use an LQI controller on the whole system. The linear velocity states are calculated with no filter and the angular velocity states are calculated with filters.
*'''RADAlqi_est''' : This macro will cause the system to use an LQI controller on the whole system. A traditional estimator is used to estimate the states.
*'''rada_lqg''' : This macro will cause the entire system to be controlled by a LQG controller/estimator system.
*'''rada_split_lqg''' : This macro will cause the pendulum and ground robot to be controlled by their own LQG systems.
*'''rada_split_lqg_ol''' : This macro will cause the pendulum to be controlled by an LQG controller, the yaw of the ground robot to be controlled by a PID controller, and the ground robot linear velocities to be controlled with open-loop commands.
*'''yaw_off''' : This macro will cause the yaw control to be disabled on some controllers.
*'''accR''' : This macro will cause the PID linear velocity controllers to be given ramps to acclerate from one velocity to another instead of steps.
*'''posRamp''' : This macro will cause the linear velocities of RADA to be controlled by position PIDs with ramp reference instead of velocity commands.
* If no controller selection is made all controllers revert to PID controllers
=== Turing on RADA ===
=== Connecting to RADA ===
== Testing RADA ==
=== Running the first test after power up ===
=== Running additional tests ===
=== Measuring battery voltages ===
=== Locating and retrieving log files ===
== Post processing and Simulation ==
=== Using the MATLAB data parsing tool ===
=== Adding additional data for simulations ===
=== Setting up the MATLAB workspace for simulation ===
=== Running simulations and storing results ===
=== Plotting results ===
db455d585115e9a1246c75ef1a32b86166b57ba1
210
209
2016-08-02T01:26:43Z
Pfuhing
5
wikitext
text/x-wiki
This page will take you though setting up and testing RADA, retrieving the log file and other necessary data to run a simulation of that test and processing the data in MATLAB. Then actually running the simulation of RADA in Simulink.
== Setting Up a RADA Test ==
Testing RADA is not overly difficult once you get the hang of the steps to setup RADA. The following steps may seem like a long process to go from starting the testing process to having completed simulation and plotting of the test results but this whole test procedure (with the exception of battery charging) can be completed in about 15-20 minutes. These steps are meant to be as detailed as possible in order to help new users of RADA to get up and running as quickly as possible.
'''<span style="color:red">NOTE: Always run RADA with at least 2 people!</span>''' The pendulum arm can crash into the ground if the network starts to drop packets and one person cannot give commands to RADA and spot the pendulum. This is a safety issue for both you and the RADA platform.
=== Charging batteries ===
The lab currently uses mostly Hyperion batteries. We charge our batteries with a Hyperion EOS 1420i Net3 battery charger. For some general information about how to use this charger see [https://www.youtube.com/watch?v=-ox3EpzvsJ8 this video.]. In the lab we power this charger using the old Kepco Power supplu because it is the only power supply that we have that can supply enough current. Make sure that the power supply is set to an output voltage between 10.5V-29V.
{| class="wikitable" style="text-align:center"
|-
| [[Image:ChargerPowerSupplyOff.JPG|400px]]
| [[Image:ChargerPowerSuplyOn.JPG|400px]]
|-
| Kepco Power Supply off.
| Kepco Power Supply on with correct voltage supply range.
|}
While the YouTube video linked above should explain how to use the charger. Currently three different Lithium polymer batteries (Lipo): 1600 mAh 2-cell Lipo for the wheels, 2600 mAh 2-cell Lipo for the electronics of Eris, and a 2600 mAh 4-cell Lipo. The 1600 mAh 2-cell Lipo can be charged using memory slot 2 of the charger. The 2600 mAh 2-cell Lipos can be charged using memory slot 3 for fast charging and memory slot 4 for slower charging (use this if the battery gets run really low for 10-20 minutes then switch to fast charging). The 2600 mAh 4-cell Lipo can be charged using memory slot 8. The 1600 mAh 2-cell and 2600 mAr 4-cell generally charge in 10-20 minutes apiece while I generally fine it takes the 2600 mAh 2-cell up to 70 minutes to charge fully.
=== Setting up the camera system ===
The camera system is run on the windows computer CO3050-07. You can log into this computer using a local microcart username and password which is not posted here for security reasons but any one who works in the lab should know it. Once logged in look for Tracking Tools in the start menu or look for the shortcut shown below:
[[Image:TrackingTools_shortcut.PNG|thumb|center|Tracking Tools shortcut]]
Once the program opens the screen should look something like this:
[[Image:NewTrackingTools.PNG|800px]]
In the Tracking Tools Quick Start pop up menu select Open Existing Project and then navigate to D:\Optitrack_Configuration (It should open to this directory by default) and select the most recent Tracking Tools project. It should be named like TrackingToolsProject YYYY-MM-DD timeStamp.ttp. This is normally the most recently edited file when sorting by data modified. The most recent one as of August 1st, 2016 is TrackingToolsProject 2015-09-23 2.30pm.ttp.
[[Image:OpeningProject.PNG|800px]]
You should notice that the cameras shown in main project scree arrange themselves like out camera configuration once the project has been opened. Now the constellations need to be loaded. This can be done by going to File->Open and another pop up window will open. Navigate back to D:\Optitrack_Configuration (It should open to this directory by default) and select the most recently dated set of RADA trackables. They are named like RADA_entireSystem_M_D_YYYY.tra. The most recent one as of August 1st, 2016 is RADA_entireSystem_7_8_2016.tra.
[[Image:Opening_trackables.PNG|800px]]
Once the project and trackless are open the cameras should appear in their constellation (square) and there should be two constellations under Project Explorer->Trackables. One Named UAV for the pendulum and one named ERIS for the ground vehicle. In order to get additional information about each constellation left click on the the name of the desired trackable.
[[Image:SelectingUAV.PNG|800px]]
Once a trackable is selected more information about it is available in the Trackables Tab on the right side of the screen. For the current position and orientation look at the Real-Time Info sub -tab. This gives the orientation in the wrong order for how we currently use the Euler angles. When two or three of the angles are near zero you can switch yaw and pitch to get roughly the correct orientation.
[[Image:Uav_realTimeInfo.PNG|800px]]
Now we need check to make sure the system is zeroed.
1. Hold RADA so that the front of the ground robot (ERIS is facing the wall with the white boards (east)). The front side of Eris is labeled. If it isn't it is the side opposite of the switches and the side with the trackable constellation on it.
2. Make sure that the motor with the red motor mount is also facing the wall with the white boards.
3. Make sure the quad system is aligned along Eris Axis by standing behind the system and seeing if you can use the pole to block mounting bolts of the front propeller motor mount when looking at the pole while facing the east wall.
4. While holding the pendulum approximately vertical see if the camera system reads zeros for the pendulum (UAV) pitch and roll (yaw and roll in Real-Time Info). If yaw is off by a few degrees that is fine.
5. Compare the yaw of the UAV to that of ERIS (Remember this is pitch in REal-Time Info). If they are both near zero and with in a few degrees and the pendulum's pitch/roll were also near zero then you are ready to use the camera system. Otherwise go to the next step.
6. You need to zero the pendulum.
- Align ERIS so it is near zero yaw first (eye ball it).
- Get a level and a friend. Have your friend use a level to ensure that the pendulum is level in both directs and hold it there.
- With the UAV constellation selected go to the Orientation tab (next to Real-Time Info tab) and click on Reset To Current Orientation button
- Now your friend can set the pendulum down and you can zero ERIS the same way.
7. Save the new trackable orientation by going to File->Save Trakables... and save a file using the same naming conventions as the trackable file you opened earlier except use the current data so you don't have to re-zero the system the next time you test.
[[Image:Uav_ResetOrientation.PNG|800px]]
=== Building Software ===
The development environment for running RADA is hosted on CO3050-11, a Linux Red Hat environment. This computer has a local ucart user name that you should use. The password isn't put here for security reasons. In order to ensure that the RADA software is setup correctly for the test you want to run. To do this you will need to open the main.cpp and logger.cpp files and make sure all of the compile time macros you want are defined correctly. All of the c++ files you should need to edit are in the directory ~/Desktop/rada_research_project/ErisResearchCode/CppProjects/MainProgram_PacketLoss/src/Korebot Below is a compiler macro options for main.cpp:
-'''H2ctrl''' : This will cause the system to enter H2 controller mode where the whole RADA system is controlled by an H2 controller.
-'''ssTracking''' : H2ctrl must also be defined for this macro to do anything. This macro will has the system to be controlled by a tracking H2 controller.
-'''ssMotors''' : H2ctrl must also be defined for this macro to do anything. This macro will has the system to be controlled by an H2 contorller that contains propeller states. This also cause the system to "Dance."
-'''ssDrop''' : Cause the system to go into packet drop controller mode. This mode allows controllers designed for lossy networks to be tested. Based off of other definitions how lossy the network is can be simulated. If nothing else is defined this controller becomes basically a H2 controller.
-'''drop10''' : Will put the packet drop mode into 10% loss mode and use a controller designed for 10% loss.
-'''drop30''' : Will put the packet drop mode into 30% loss mode and use a controller designed for 30% loss.
-'''drop50''' : Will put the packet drop mode into 50% loss mode and use a controller designed for 50% loss.
-'''mot50''' : This macro over-rides all other macros. If this is turned on the wheels will not run and the propllers will be run at 50% command. This is used for measuring the effective battery voltage seen by the ESCs. This is always run after a test.
-'''RADAlqi''' : This macro will cause the system to use an LQI controller on the whole system. The linear velocity states are calculated with no filter and the angular velocity states are calculated with filters.
-'''RADAlqi_est''' : This macro will cause the system to use an LQI controller on the whole system. A traditional estimator is used to estimate the states.
-'''rada_lqg''' : This macro will cause the entire system to be controlled by a LQG controller/estimator system.
-'''rada_split_lqg''' : This macro will cause the pendulum and ground robot to be controlled by their own LQG systems.
-'''rada_split_lqg_ol''' : This macro will cause the pendulum to be controlled by an LQG controller, the yaw of the ground robot to be controlled by a PID controller, and the ground robot linear velocities to be controlled with open-loop commands.
-'''yaw_off''' : This macro will cause the yaw control to be disabled on some controllers.
*'''accR''' : This macro will cause the PID linear velocity controllers to be given ramps to acclerate from one velocity to another instead of steps.
-'''posRamp''' : This macro will cause the linear velocities of RADA to be controlled by position PIDs with ramp reference instead of velocity commands.
-If no controller selection is made all controllers revert to PID controllers
=== Turing on RADA ===
=== Connecting to RADA ===
== Testing RADA ==
=== Running the first test after power up ===
=== Running additional tests ===
=== Measuring battery voltages ===
=== Locating and retrieving log files ===
== Post processing and Simulation ==
=== Using the MATLAB data parsing tool ===
=== Adding additional data for simulations ===
=== Setting up the MATLAB workspace for simulation ===
=== Running simulations and storing results ===
=== Plotting results ===
6992a91adfabfc2b2b95fa992c0527fa9844ccf2
211
210
2016-08-02T01:41:19Z
Pfuhing
5
wikitext
text/x-wiki
This page will take you though setting up and testing RADA, retrieving the log file and other necessary data to run a simulation of that test and processing the data in MATLAB. Then actually running the simulation of RADA in Simulink.
== Setting Up a RADA Test ==
Testing RADA is not overly difficult once you get the hang of the steps to setup RADA. The following steps may seem like a long process to go from starting the testing process to having completed simulation and plotting of the test results but this whole test procedure (with the exception of battery charging) can be completed in about 15-20 minutes. These steps are meant to be as detailed as possible in order to help new users of RADA to get up and running as quickly as possible.
'''<span style="color:red">NOTE: Always run RADA with at least 2 people!</span>''' The pendulum arm can crash into the ground if the network starts to drop packets and one person cannot give commands to RADA and spot the pendulum. This is a safety issue for both you and the RADA platform.
=== Charging batteries ===
The lab currently uses mostly Hyperion batteries. We charge our batteries with a Hyperion EOS 1420i Net3 battery charger. For some general information about how to use this charger see [https://www.youtube.com/watch?v=-ox3EpzvsJ8 this video.]. In the lab we power this charger using the old Kepco Power supplu because it is the only power supply that we have that can supply enough current. Make sure that the power supply is set to an output voltage between 10.5V-29V.
{| class="wikitable" style="text-align:center"
|-
| [[Image:ChargerPowerSupplyOff.JPG|400px]]
| [[Image:ChargerPowerSuplyOn.JPG|400px]]
|-
| Kepco Power Supply off.
| Kepco Power Supply on with correct voltage supply range.
|}
While the YouTube video linked above should explain how to use the charger. Currently three different Lithium polymer batteries (Lipo): 1600 mAh 2-cell Lipo for the wheels, 2600 mAh 2-cell Lipo for the electronics of Eris, and a 2600 mAh 4-cell Lipo. The 1600 mAh 2-cell Lipo can be charged using memory slot 2 of the charger. The 2600 mAh 2-cell Lipos can be charged using memory slot 3 for fast charging and memory slot 4 for slower charging (use this if the battery gets run really low for 10-20 minutes then switch to fast charging). The 2600 mAh 4-cell Lipo can be charged using memory slot 8. The 1600 mAh 2-cell and 2600 mAr 4-cell generally charge in 10-20 minutes apiece while I generally fine it takes the 2600 mAh 2-cell up to 70 minutes to charge fully.
=== Setting up the camera system ===
The camera system is run on the windows computer CO3050-07. You can log into this computer using a local microcart username and password which is not posted here for security reasons but any one who works in the lab should know it. Once logged in look for Tracking Tools in the start menu or look for the shortcut shown below:
[[Image:TrackingTools_shortcut.PNG|thumb|center|Tracking Tools shortcut]]
Once the program opens the screen should look something like this:
[[Image:NewTrackingTools.PNG|800px]]
In the Tracking Tools Quick Start pop up menu select Open Existing Project and then navigate to D:\Optitrack_Configuration (It should open to this directory by default) and select the most recent Tracking Tools project. It should be named like TrackingToolsProject YYYY-MM-DD timeStamp.ttp. This is normally the most recently edited file when sorting by data modified. The most recent one as of August 1st, 2016 is TrackingToolsProject 2015-09-23 2.30pm.ttp.
[[Image:OpeningProject.PNG|800px]]
You should notice that the cameras shown in main project scree arrange themselves like out camera configuration once the project has been opened. Now the constellations need to be loaded. This can be done by going to File->Open and another pop up window will open. Navigate back to D:\Optitrack_Configuration (It should open to this directory by default) and select the most recently dated set of RADA trackables. They are named like RADA_entireSystem_M_D_YYYY.tra. The most recent one as of August 1st, 2016 is RADA_entireSystem_7_8_2016.tra.
[[Image:Opening_trackables.PNG|800px]]
Once the project and trackless are open the cameras should appear in their constellation (square) and there should be two constellations under Project Explorer->Trackables. One Named UAV for the pendulum and one named ERIS for the ground vehicle. In order to get additional information about each constellation left click on the the name of the desired trackable.
[[Image:SelectingUAV.PNG|800px]]
Once a trackable is selected more information about it is available in the Trackables Tab on the right side of the screen. For the current position and orientation look at the Real-Time Info sub -tab. This gives the orientation in the wrong order for how we currently use the Euler angles. When two or three of the angles are near zero you can switch yaw and pitch to get roughly the correct orientation.
[[Image:Uav_realTimeInfo.PNG|800px]]
Now we need check to make sure the system is zeroed.
1. Hold RADA so that the front of the ground robot (ERIS is facing the wall with the white boards (east)). The front side of Eris is labeled. If it isn't it is the side opposite of the switches and the side with the trackable constellation on it.
2. Make sure that the motor with the red motor mount is also facing the wall with the white boards.
3. Make sure the quad system is aligned along Eris Axis by standing behind the system and seeing if you can use the pole to block mounting bolts of the front propeller motor mount when looking at the pole while facing the east wall.
4. While holding the pendulum approximately vertical see if the camera system reads zeros for the pendulum (UAV) pitch and roll (yaw and roll in Real-Time Info). If yaw is off by a few degrees that is fine.
5. Compare the yaw of the UAV to that of ERIS (Remember this is pitch in REal-Time Info). If they are both near zero and with in a few degrees and the pendulum's pitch/roll were also near zero then you are ready to use the camera system. Otherwise go to the next step.
6. You need to zero the pendulum.
- Align ERIS so it is near zero yaw first (eye ball it).
- Get a level and a friend. Have your friend use a level to ensure that the pendulum is level in both directs and hold it there.
- With the UAV constellation selected go to the Orientation tab (next to Real-Time Info tab) and click on Reset To Current Orientation button
- Now your friend can set the pendulum down and you can zero ERIS the same way.
7. Save the new trackable orientation by going to File->Save Trakables... and save a file using the same naming conventions as the trackable file you opened earlier except use the current data so you don't have to re-zero the system the next time you test.
[[Image:Uav_ResetOrientation.PNG|800px]]
=== Building Software ===
The development environment for running RADA is hosted on CO3050-11, a Linux Red Hat environment. This computer has a local ucart user name that you should use. The password isn't put here for security reasons. In order to ensure that the RADA software is setup correctly for the test you want to run. To do this you will need to open the main.cpp and logger.cpp files and make sure all of the compile time macros you want are defined correctly. All of the c++ files you should need to edit are in the directory ~/Desktop/rada_research_project/ErisResearchCode/CppProjects/MainProgram_PacketLoss/src/Korebot Below is a compiler macro options for main.cpp:
-'''H2ctrl''' : This will cause the system to enter H2 controller mode where the whole RADA system is controlled by an H2 controller.
-'''ssTracking''' : H2ctrl must also be defined for this macro to do anything. This macro will has the system to be controlled by a tracking H2 controller.
-'''ssMotors''' : H2ctrl must also be defined for this macro to do anything. This macro will has the system to be controlled by an H2 contorller that contains propeller states. This also cause the system to "Dance."
-'''ssDrop''' : Cause the system to go into packet drop controller mode. This mode allows controllers designed for lossy networks to be tested. Based off of other definitions how lossy the network is can be simulated. If nothing else is defined this controller becomes basically a H2 controller.
-'''drop10''' : Will put the packet drop mode into 10% loss mode and use a controller designed for 10% loss.
-'''drop30''' : Will put the packet drop mode into 30% loss mode and use a controller designed for 30% loss.
-'''drop50''' : Will put the packet drop mode into 50% loss mode and use a controller designed for 50% loss.
-'''mot50''' : This macro over-rides all other macros. If this is turned on the wheels will not run and the propllers will be run at 50% command. This is used for measuring the effective battery voltage seen by the ESCs. This is always run after a test.
-'''RADAlqi''' : This macro will cause the system to use an LQI controller on the whole system. The linear velocity states are calculated with no filter and the angular velocity states are calculated with filters.
-'''RADAlqi_est''' : This macro will cause the system to use an LQI controller on the whole system. A traditional estimator is used to estimate the states.
-'''rada_lqg''' : This macro will cause the entire system to be controlled by a LQG controller/estimator system.
-'''rada_split_lqg''' : This macro will cause the pendulum and ground robot to be controlled by their own LQG systems.
-'''rada_split_lqg_ol''' : This macro will cause the pendulum to be controlled by an LQG controller, the yaw of the ground robot to be controlled by a PID controller, and the ground robot linear velocities to be controlled with open-loop commands.
-'''yaw_off''' : This macro will cause the yaw control to be disabled on some controllers.
*'''accR''' : This macro will cause the PID linear velocity controllers to be given ramps to acclerate from one velocity to another instead of steps.
-'''posRamp''' : This macro will cause the linear velocities of RADA to be controlled by position PIDs with ramp reference instead of velocity commands.
-If no controller selection is made all controllers revert to PID controllers
All of these macros can be defined simply by uncommenting the corresponding define statement in main.cpp. The macros in the logger.cpp can be seen below:
-'''ssDrop''' : This macro puts the logger into packed drop controller mode and logs the correct values for the packet drop controllers.
-'''RADAlqi''' : This macro puts the logger into full system LQI controller logging mode.
-'''RADAlqi_est''' : This macro puts the logger into full system LQI controller plus estimator logging mode.
-'''rada_lqg''' : This puts the logger into full system LQG controller logging mode.
-'''rada_split_lqg''' : This macro causes the logger to log data about the subsystem LQG controllers.
-'''rada_split_lqg_ol''' : This cause the system to log data about the pendulum LQG system and the open-loop linear velocity commands.
-'''H2ctrl''' : This macro causes the logger to log data about the full system H2 controllers.
-If no logging mode is selected then the logger will default to logging PID data.
Because the system only calculates controllers for one set of controllers it is important to ensure that the logger is in the correct mode based off of what is defined in main.cpp. As of August 1st, 2016 the defines in main.cpp are not seen in logger.cpp.
Finally in a command prompt navigate to the driectroy: ~/Desktop/rada_research_project/ErisResearchCode/CppProjects/MainProgram_PacketLoss
Here just type: make. The code will compile for your desired mode. FOr setting up a new development directory see [http://wikis.ece.iastate.edu/robotic-agriculture-data-acquisition/index.php/Setting_up_a_new_development_environment Setting up a new development environment] from the RADA senior Design wiki.
The corect define
=== Turing on RADA ===
=== Connecting to RADA ===
== Testing RADA ==
=== Running the first test after power up ===
=== Running additional tests ===
=== Measuring battery voltages ===
=== Locating and retrieving log files ===
== Post processing and Simulation ==
=== Using the MATLAB data parsing tool ===
=== Adding additional data for simulations ===
=== Setting up the MATLAB workspace for simulation ===
=== Running simulations and storing results ===
=== Plotting results ===
14f01a45183d49d9a035029d8f8bde25cd4b76a3
214
211
2016-08-02T01:52:43Z
Pfuhing
5
wikitext
text/x-wiki
This page will take you though setting up and testing RADA, retrieving the log file and other necessary data to run a simulation of that test and processing the data in MATLAB. Then actually running the simulation of RADA in Simulink.
== Setting Up a RADA Test ==
Testing RADA is not overly difficult once you get the hang of the steps to setup RADA. The following steps may seem like a long process to go from starting the testing process to having completed simulation and plotting of the test results but this whole test procedure (with the exception of battery charging) can be completed in about 15-20 minutes. These steps are meant to be as detailed as possible in order to help new users of RADA to get up and running as quickly as possible.
'''<span style="color:red">NOTE: Always run RADA with at least 2 people!</span>''' The pendulum arm can crash into the ground if the network starts to drop packets and one person cannot give commands to RADA and spot the pendulum. This is a safety issue for both you and the RADA platform.
=== Charging batteries ===
The lab currently uses mostly Hyperion batteries. We charge our batteries with a Hyperion EOS 1420i Net3 battery charger. For some general information about how to use this charger see [https://www.youtube.com/watch?v=-ox3EpzvsJ8 this video.]. In the lab we power this charger using the old Kepco Power supplu because it is the only power supply that we have that can supply enough current. Make sure that the power supply is set to an output voltage between 10.5V-29V.
{| class="wikitable" style="text-align:center"
|-
| [[Image:ChargerPowerSupplyOff.JPG|400px]]
| [[Image:ChargerPowerSuplyOn.JPG|400px]]
|-
| Kepco Power Supply off.
| Kepco Power Supply on with correct voltage supply range.
|}
While the YouTube video linked above should explain how to use the charger. Currently three different Lithium polymer batteries (Lipo): 1600 mAh 2-cell Lipo for the wheels, 2600 mAh 2-cell Lipo for the electronics of Eris, and a 2600 mAh 4-cell Lipo. The 1600 mAh 2-cell Lipo can be charged using memory slot 2 of the charger. The 2600 mAh 2-cell Lipos can be charged using memory slot 3 for fast charging and memory slot 4 for slower charging (use this if the battery gets run really low for 10-20 minutes then switch to fast charging). The 2600 mAh 4-cell Lipo can be charged using memory slot 8. The 1600 mAh 2-cell and 2600 mAr 4-cell generally charge in 10-20 minutes apiece while I generally fine it takes the 2600 mAh 2-cell up to 70 minutes to charge fully.
=== Setting up the camera system ===
The camera system is run on the windows computer CO3050-07. You can log into this computer using a local microcart username and password which is not posted here for security reasons but any one who works in the lab should know it. Once logged in look for Tracking Tools in the start menu or look for the shortcut shown below:
[[Image:TrackingTools_shortcut.PNG|thumb|center|Tracking Tools shortcut]]
Once the program opens the screen should look something like this:
[[Image:NewTrackingTools.PNG|800px]]
In the Tracking Tools Quick Start pop up menu select Open Existing Project and then navigate to D:\Optitrack_Configuration (It should open to this directory by default) and select the most recent Tracking Tools project. It should be named like TrackingToolsProject YYYY-MM-DD timeStamp.ttp. This is normally the most recently edited file when sorting by data modified. The most recent one as of August 1st, 2016 is TrackingToolsProject 2015-09-23 2.30pm.ttp.
[[Image:OpeningProject.PNG|800px]]
You should notice that the cameras shown in main project scree arrange themselves like out camera configuration once the project has been opened. Now the constellations need to be loaded. This can be done by going to File->Open and another pop up window will open. Navigate back to D:\Optitrack_Configuration (It should open to this directory by default) and select the most recently dated set of RADA trackables. They are named like RADA_entireSystem_M_D_YYYY.tra. The most recent one as of August 1st, 2016 is RADA_entireSystem_7_8_2016.tra.
[[Image:Opening_trackables.PNG|800px]]
Once the project and trackless are open the cameras should appear in their constellation (square) and there should be two constellations under Project Explorer->Trackables. One Named UAV for the pendulum and one named ERIS for the ground vehicle. In order to get additional information about each constellation left click on the the name of the desired trackable.
[[Image:SelectingUAV.PNG|800px]]
Once a trackable is selected more information about it is available in the Trackables Tab on the right side of the screen. For the current position and orientation look at the Real-Time Info sub -tab. This gives the orientation in the wrong order for how we currently use the Euler angles. When two or three of the angles are near zero you can switch yaw and pitch to get roughly the correct orientation.
[[Image:Uav_realTimeInfo.PNG|800px]]
Now we need check to make sure the system is zeroed.
1. Hold RADA so that the front of the ground robot (ERIS is facing the wall with the white boards (east)). The front side of Eris is labeled. If it isn't it is the side opposite of the switches and the side with the trackable constellation on it.
2. Make sure that the motor with the red motor mount is also facing the wall with the white boards.
3. Make sure the quad system is aligned along Eris Axis by standing behind the system and seeing if you can use the pole to block mounting bolts of the front propeller motor mount when looking at the pole while facing the east wall.
4. While holding the pendulum approximately vertical see if the camera system reads zeros for the pendulum (UAV) pitch and roll (yaw and roll in Real-Time Info). If yaw is off by a few degrees that is fine.
5. Compare the yaw of the UAV to that of ERIS (Remember this is pitch in REal-Time Info). If they are both near zero and with in a few degrees and the pendulum's pitch/roll were also near zero then you are ready to use the camera system. Otherwise go to the next step.
6. You need to zero the pendulum.
- Align ERIS so it is near zero yaw first (eye ball it).
- Get a level and a friend. Have your friend use a level to ensure that the pendulum is level in both directs and hold it there.
- With the UAV constellation selected go to the Orientation tab (next to Real-Time Info tab) and click on Reset To Current Orientation button
- Now your friend can set the pendulum down and you can zero ERIS the same way.
7. Save the new trackable orientation by going to File->Save Trakables... and save a file using the same naming conventions as the trackable file you opened earlier except use the current data so you don't have to re-zero the system the next time you test.
[[Image:Uav_ResetOrientation.PNG|800px]]
=== Building Software ===
The development environment for running RADA is hosted on CO3050-11, a Linux Red Hat environment. This computer has a local ucart user name that you should use. The password isn't put here for security reasons. In order to ensure that the RADA software is setup correctly for the test you want to run. To do this you will need to open the main.cpp and logger.cpp files and make sure all of the compile time macros you want are defined correctly. All of the c++ files you should need to edit are in the directory ~/Desktop/rada_research_project/ErisResearchCode/CppProjects/MainProgram_PacketLoss/src/Korebot Below is a compiler macro options for main.cpp:
-'''H2ctrl''' : This will cause the system to enter H2 controller mode where the whole RADA system is controlled by an H2 controller.
-'''ssTracking''' : H2ctrl must also be defined for this macro to do anything. This macro will has the system to be controlled by a tracking H2 controller.
-'''ssMotors''' : H2ctrl must also be defined for this macro to do anything. This macro will has the system to be controlled by an H2 contorller that contains propeller states. This also cause the system to "Dance."
-'''ssDrop''' : Cause the system to go into packet drop controller mode. This mode allows controllers designed for lossy networks to be tested. Based off of other definitions how lossy the network is can be simulated. If nothing else is defined this controller becomes basically a H2 controller.
-'''drop10''' : Will put the packet drop mode into 10% loss mode and use a controller designed for 10% loss.
-'''drop30''' : Will put the packet drop mode into 30% loss mode and use a controller designed for 30% loss.
-'''drop50''' : Will put the packet drop mode into 50% loss mode and use a controller designed for 50% loss.
-'''mot50''' : This macro over-rides all other macros. If this is turned on the wheels will not run and the propllers will be run at 50% command. This is used for measuring the effective battery voltage seen by the ESCs. This is always run after a test.
-'''RADAlqi''' : This macro will cause the system to use an LQI controller on the whole system. The linear velocity states are calculated with no filter and the angular velocity states are calculated with filters.
-'''RADAlqi_est''' : This macro will cause the system to use an LQI controller on the whole system. A traditional estimator is used to estimate the states.
-'''rada_lqg''' : This macro will cause the entire system to be controlled by a LQG controller/estimator system.
-'''rada_split_lqg''' : This macro will cause the pendulum and ground robot to be controlled by their own LQG systems.
-'''rada_split_lqg_ol''' : This macro will cause the pendulum to be controlled by an LQG controller, the yaw of the ground robot to be controlled by a PID controller, and the ground robot linear velocities to be controlled with open-loop commands.
-'''yaw_off''' : This macro will cause the yaw control to be disabled on some controllers.
*'''accR''' : This macro will cause the PID linear velocity controllers to be given ramps to acclerate from one velocity to another instead of steps.
-'''posRamp''' : This macro will cause the linear velocities of RADA to be controlled by position PIDs with ramp reference instead of velocity commands.
-If no controller selection is made all controllers revert to PID controllers
All of these macros can be defined simply by uncommenting the corresponding define statement in main.cpp. The macros in the logger.cpp can be seen below:
-'''ssDrop''' : This macro puts the logger into packed drop controller mode and logs the correct values for the packet drop controllers.
-'''RADAlqi''' : This macro puts the logger into full system LQI controller logging mode.
-'''RADAlqi_est''' : This macro puts the logger into full system LQI controller plus estimator logging mode.
-'''rada_lqg''' : This puts the logger into full system LQG controller logging mode.
-'''rada_split_lqg''' : This macro causes the logger to log data about the subsystem LQG controllers.
-'''rada_split_lqg_ol''' : This cause the system to log data about the pendulum LQG system and the open-loop linear velocity commands.
-'''H2ctrl''' : This macro causes the logger to log data about the full system H2 controllers.
-If no logging mode is selected then the logger will default to logging PID data.
Because the system only calculates controllers for one set of controllers it is important to ensure that the logger is in the correct mode based off of what is defined in main.cpp. As of August 1st, 2016 the defines in main.cpp are not seen in logger.cpp.
Finally in a command prompt navigate to the driectroy: ~/Desktop/rada_research_project/ErisResearchCode/CppProjects/MainProgram_PacketLoss
Here just type: make. The code will compile for your desired mode. For setting up a new development directory see [http://wikis.ece.iastate.edu/robotic-agriculture-data-acquisition/index.php/Setting_up_a_new_development_environment Setting up a new development environment] from the RADA senior Design wiki.
[[Image:ComplingRADACode.png|800px]]
The complied executable code ends up in /home/shared/MainProject. The /home/shared directory is setup as a network file share (NFS).
[[Image:ComplingRADACode-config.png|800px]]
This service needs to be restarted when CO3050-11 is restarted. [http://wikis.ece.iastate.edu/robotic-agriculture-data-acquisition/index.php/Configuring_NFS_shares_for_the_robot Configure NFS shares for the robot] from the RADA Senior Design wiki. Be sure to use the new Linux install command in step six. Though I have fond that even on a good strt the ''[ok]'' messages will still print.
=== Turing on RADA ===
=== Connecting to RADA ===
== Testing RADA ==
=== Running the first test after power up ===
=== Running additional tests ===
=== Measuring battery voltages ===
=== Locating and retrieving log files ===
== Post processing and Simulation ==
=== Using the MATLAB data parsing tool ===
=== Adding additional data for simulations ===
=== Setting up the MATLAB workspace for simulation ===
=== Running simulations and storing results ===
=== Plotting results ===
8d081441065f2eec4c47583d7d2b4e6641b50bb9
215
214
2016-08-02T01:53:25Z
Pfuhing
5
wikitext
text/x-wiki
This page will take you though setting up and testing RADA, retrieving the log file and other necessary data to run a simulation of that test and processing the data in MATLAB. Then actually running the simulation of RADA in Simulink.
== Setting Up a RADA Test ==
Testing RADA is not overly difficult once you get the hang of the steps to setup RADA. The following steps may seem like a long process to go from starting the testing process to having completed simulation and plotting of the test results but this whole test procedure (with the exception of battery charging) can be completed in about 15-20 minutes. These steps are meant to be as detailed as possible in order to help new users of RADA to get up and running as quickly as possible.
'''<span style="color:red">NOTE: Always run RADA with at least 2 people!</span>''' The pendulum arm can crash into the ground if the network starts to drop packets and one person cannot give commands to RADA and spot the pendulum. This is a safety issue for both you and the RADA platform.
=== Charging batteries ===
The lab currently uses mostly Hyperion batteries. We charge our batteries with a Hyperion EOS 1420i Net3 battery charger. For some general information about how to use this charger see [https://www.youtube.com/watch?v=-ox3EpzvsJ8 this video.]. In the lab we power this charger using the old Kepco Power supplu because it is the only power supply that we have that can supply enough current. Make sure that the power supply is set to an output voltage between 10.5V-29V.
{| class="wikitable" style="text-align:center"
|-
| [[Image:ChargerPowerSupplyOff.JPG|400px]]
| [[Image:ChargerPowerSuplyOn.JPG|400px]]
|-
| Kepco Power Supply off.
| Kepco Power Supply on with correct voltage supply range.
|}
While the YouTube video linked above should explain how to use the charger. Currently three different Lithium polymer batteries (Lipo): 1600 mAh 2-cell Lipo for the wheels, 2600 mAh 2-cell Lipo for the electronics of Eris, and a 2600 mAh 4-cell Lipo. The 1600 mAh 2-cell Lipo can be charged using memory slot 2 of the charger. The 2600 mAh 2-cell Lipos can be charged using memory slot 3 for fast charging and memory slot 4 for slower charging (use this if the battery gets run really low for 10-20 minutes then switch to fast charging). The 2600 mAh 4-cell Lipo can be charged using memory slot 8. The 1600 mAh 2-cell and 2600 mAr 4-cell generally charge in 10-20 minutes apiece while I generally fine it takes the 2600 mAh 2-cell up to 70 minutes to charge fully.
=== Setting up the camera system ===
The camera system is run on the windows computer CO3050-07. You can log into this computer using a local microcart username and password which is not posted here for security reasons but any one who works in the lab should know it. Once logged in look for Tracking Tools in the start menu or look for the shortcut shown below:
[[Image:TrackingTools_shortcut.PNG|thumb|center|Tracking Tools shortcut]]
Once the program opens the screen should look something like this:
[[Image:NewTrackingTools.PNG|800px]]
In the Tracking Tools Quick Start pop up menu select Open Existing Project and then navigate to D:\Optitrack_Configuration (It should open to this directory by default) and select the most recent Tracking Tools project. It should be named like TrackingToolsProject YYYY-MM-DD timeStamp.ttp. This is normally the most recently edited file when sorting by data modified. The most recent one as of August 1st, 2016 is TrackingToolsProject 2015-09-23 2.30pm.ttp.
[[Image:OpeningProject.PNG|800px]]
You should notice that the cameras shown in main project scree arrange themselves like out camera configuration once the project has been opened. Now the constellations need to be loaded. This can be done by going to File->Open and another pop up window will open. Navigate back to D:\Optitrack_Configuration (It should open to this directory by default) and select the most recently dated set of RADA trackables. They are named like RADA_entireSystem_M_D_YYYY.tra. The most recent one as of August 1st, 2016 is RADA_entireSystem_7_8_2016.tra.
[[Image:Opening_trackables.PNG|800px]]
Once the project and trackless are open the cameras should appear in their constellation (square) and there should be two constellations under Project Explorer->Trackables. One Named UAV for the pendulum and one named ERIS for the ground vehicle. In order to get additional information about each constellation left click on the the name of the desired trackable.
[[Image:SelectingUAV.PNG|800px]]
Once a trackable is selected more information about it is available in the Trackables Tab on the right side of the screen. For the current position and orientation look at the Real-Time Info sub -tab. This gives the orientation in the wrong order for how we currently use the Euler angles. When two or three of the angles are near zero you can switch yaw and pitch to get roughly the correct orientation.
[[Image:Uav_realTimeInfo.PNG|800px]]
Now we need check to make sure the system is zeroed.
1. Hold RADA so that the front of the ground robot (ERIS is facing the wall with the white boards (east)). The front side of Eris is labeled. If it isn't it is the side opposite of the switches and the side with the trackable constellation on it.
2. Make sure that the motor with the red motor mount is also facing the wall with the white boards.
3. Make sure the quad system is aligned along Eris Axis by standing behind the system and seeing if you can use the pole to block mounting bolts of the front propeller motor mount when looking at the pole while facing the east wall.
4. While holding the pendulum approximately vertical see if the camera system reads zeros for the pendulum (UAV) pitch and roll (yaw and roll in Real-Time Info). If yaw is off by a few degrees that is fine.
5. Compare the yaw of the UAV to that of ERIS (Remember this is pitch in REal-Time Info). If they are both near zero and with in a few degrees and the pendulum's pitch/roll were also near zero then you are ready to use the camera system. Otherwise go to the next step.
6. You need to zero the pendulum.
- Align ERIS so it is near zero yaw first (eye ball it).
- Get a level and a friend. Have your friend use a level to ensure that the pendulum is level in both directs and hold it there.
- With the UAV constellation selected go to the Orientation tab (next to Real-Time Info tab) and click on Reset To Current Orientation button
- Now your friend can set the pendulum down and you can zero ERIS the same way.
7. Save the new trackable orientation by going to File->Save Trakables... and save a file using the same naming conventions as the trackable file you opened earlier except use the current data so you don't have to re-zero the system the next time you test.
[[Image:Uav_ResetOrientation.PNG|800px]]
=== Building Software ===
The development environment for running RADA is hosted on CO3050-11, a Linux Red Hat environment. This computer has a local ucart user name that you should use. The password isn't put here for security reasons. In order to ensure that the RADA software is setup correctly for the test you want to run. To do this you will need to open the main.cpp and logger.cpp files and make sure all of the compile time macros you want are defined correctly. All of the c++ files you should need to edit are in the directory ~/Desktop/rada_research_project/ErisResearchCode/CppProjects/MainProgram_PacketLoss/src/Korebot Below is a compiler macro options for main.cpp:
-'''H2ctrl''' : This will cause the system to enter H2 controller mode where the whole RADA system is controlled by an H2 controller.
-'''ssTracking''' : H2ctrl must also be defined for this macro to do anything. This macro will has the system to be controlled by a tracking H2 controller.
-'''ssMotors''' : H2ctrl must also be defined for this macro to do anything. This macro will has the system to be controlled by an H2 contorller that contains propeller states. This also cause the system to "Dance."
-'''ssDrop''' : Cause the system to go into packet drop controller mode. This mode allows controllers designed for lossy networks to be tested. Based off of other definitions how lossy the network is can be simulated. If nothing else is defined this controller becomes basically a H2 controller.
-'''drop10''' : Will put the packet drop mode into 10% loss mode and use a controller designed for 10% loss.
-'''drop30''' : Will put the packet drop mode into 30% loss mode and use a controller designed for 30% loss.
-'''drop50''' : Will put the packet drop mode into 50% loss mode and use a controller designed for 50% loss.
-'''mot50''' : This macro over-rides all other macros. If this is turned on the wheels will not run and the propllers will be run at 50% command. This is used for measuring the effective battery voltage seen by the ESCs. This is always run after a test.
-'''RADAlqi''' : This macro will cause the system to use an LQI controller on the whole system. The linear velocity states are calculated with no filter and the angular velocity states are calculated with filters.
-'''RADAlqi_est''' : This macro will cause the system to use an LQI controller on the whole system. A traditional estimator is used to estimate the states.
-'''rada_lqg''' : This macro will cause the entire system to be controlled by a LQG controller/estimator system.
-'''rada_split_lqg''' : This macro will cause the pendulum and ground robot to be controlled by their own LQG systems.
-'''rada_split_lqg_ol''' : This macro will cause the pendulum to be controlled by an LQG controller, the yaw of the ground robot to be controlled by a PID controller, and the ground robot linear velocities to be controlled with open-loop commands.
-'''yaw_off''' : This macro will cause the yaw control to be disabled on some controllers.
*'''accR''' : This macro will cause the PID linear velocity controllers to be given ramps to acclerate from one velocity to another instead of steps.
-'''posRamp''' : This macro will cause the linear velocities of RADA to be controlled by position PIDs with ramp reference instead of velocity commands.
-If no controller selection is made all controllers revert to PID controllers
All of these macros can be defined simply by uncommenting the corresponding define statement in main.cpp. The macros in the logger.cpp can be seen below:
-'''ssDrop''' : This macro puts the logger into packed drop controller mode and logs the correct values for the packet drop controllers.
-'''RADAlqi''' : This macro puts the logger into full system LQI controller logging mode.
-'''RADAlqi_est''' : This macro puts the logger into full system LQI controller plus estimator logging mode.
-'''rada_lqg''' : This puts the logger into full system LQG controller logging mode.
-'''rada_split_lqg''' : This macro causes the logger to log data about the subsystem LQG controllers.
-'''rada_split_lqg_ol''' : This cause the system to log data about the pendulum LQG system and the open-loop linear velocity commands.
-'''H2ctrl''' : This macro causes the logger to log data about the full system H2 controllers.
-If no logging mode is selected then the logger will default to logging PID data.
Because the system only calculates controllers for one set of controllers it is important to ensure that the logger is in the correct mode based off of what is defined in main.cpp. As of August 1st, 2016 the defines in main.cpp are not seen in logger.cpp.
Finally in a command prompt navigate to the driectroy: ~/Desktop/rada_research_project/ErisResearchCode/CppProjects/MainProgram_PacketLoss
Here just type: make. The code will compile for your desired mode. For setting up a new development directory see [http://wikis.ece.iastate.edu/robotic-agriculture-data-acquisition/index.php/Setting_up_a_new_development_environment Setting up a new development environment] from the RADA senior Design wiki.
[[Image:ComplingRADACode.png|800px]]
The complied executable code ends up in /home/shared/MainProject. The /home/shared directory is setup as a network file share (NFS).
[[Image:ErisCompliedCode-config.png|800px]]
This service needs to be restarted when CO3050-11 is restarted. [http://wikis.ece.iastate.edu/robotic-agriculture-data-acquisition/index.php/Configuring_NFS_shares_for_the_robot Configure NFS shares for the robot] from the RADA Senior Design wiki. Be sure to use the new Linux install command in step six. Though I have fond that even on a good strt the ''[ok]'' messages will still print.
=== Turing on RADA ===
=== Connecting to RADA ===
== Testing RADA ==
=== Running the first test after power up ===
=== Running additional tests ===
=== Measuring battery voltages ===
=== Locating and retrieving log files ===
== Post processing and Simulation ==
=== Using the MATLAB data parsing tool ===
=== Adding additional data for simulations ===
=== Setting up the MATLAB workspace for simulation ===
=== Running simulations and storing results ===
=== Plotting results ===
31bad6d285f6fd26d4b53eb7a223a36279943293
217
215
2016-08-02T02:06:17Z
Pfuhing
5
wikitext
text/x-wiki
This page will take you though setting up and testing RADA, retrieving the log file and other necessary data to run a simulation of that test and processing the data in MATLAB. Then actually running the simulation of RADA in Simulink.
== Setting Up a RADA Test ==
Testing RADA is not overly difficult once you get the hang of the steps to setup RADA. The following steps may seem like a long process to go from starting the testing process to having completed simulation and plotting of the test results but this whole test procedure (with the exception of battery charging) can be completed in about 15-20 minutes. These steps are meant to be as detailed as possible in order to help new users of RADA to get up and running as quickly as possible.
'''<span style="color:red">NOTE: Always run RADA with at least 2 people!</span>''' The pendulum arm can crash into the ground if the network starts to drop packets and one person cannot give commands to RADA and spot the pendulum. This is a safety issue for both you and the RADA platform.
=== Charging batteries ===
The lab currently uses mostly Hyperion batteries. We charge our batteries with a Hyperion EOS 1420i Net3 battery charger. For some general information about how to use this charger see [https://www.youtube.com/watch?v=-ox3EpzvsJ8 this video.]. In the lab we power this charger using the old Kepco Power supplu because it is the only power supply that we have that can supply enough current. Make sure that the power supply is set to an output voltage between 10.5V-29V.
{| class="wikitable" style="text-align:center"
|-
| [[Image:ChargerPowerSupplyOff.JPG|400px]]
| [[Image:ChargerPowerSuplyOn.JPG|400px]]
|-
| Kepco Power Supply off.
| Kepco Power Supply on with correct voltage supply range.
|}
While the YouTube video linked above should explain how to use the charger. Currently three different Lithium polymer batteries (Lipo): 1600 mAh 2-cell Lipo for the wheels, 2600 mAh 2-cell Lipo for the electronics of Eris, and a 2600 mAh 4-cell Lipo. The 1600 mAh 2-cell Lipo can be charged using memory slot 2 of the charger. The 2600 mAh 2-cell Lipos can be charged using memory slot 3 for fast charging and memory slot 4 for slower charging (use this if the battery gets run really low for 10-20 minutes then switch to fast charging). The 2600 mAh 4-cell Lipo can be charged using memory slot 8. The 1600 mAh 2-cell and 2600 mAr 4-cell generally charge in 10-20 minutes apiece while I generally fine it takes the 2600 mAh 2-cell up to 70 minutes to charge fully.
=== Setting up the camera system ===
The camera system is run on the windows computer CO3050-07. You can log into this computer using a local microcart username and password which is not posted here for security reasons but any one who works in the lab should know it. Once logged in look for Tracking Tools in the start menu or look for the shortcut shown below:
[[Image:TrackingTools_shortcut.PNG|thumb|center|Tracking Tools shortcut]]
Once the program opens the screen should look something like this:
[[Image:NewTrackingTools.PNG|800px]]
In the Tracking Tools Quick Start pop up menu select Open Existing Project and then navigate to D:\Optitrack_Configuration (It should open to this directory by default) and select the most recent Tracking Tools project. It should be named like TrackingToolsProject YYYY-MM-DD timeStamp.ttp. This is normally the most recently edited file when sorting by data modified. The most recent one as of August 1st, 2016 is TrackingToolsProject 2015-09-23 2.30pm.ttp.
[[Image:OpeningProject.PNG|800px]]
You should notice that the cameras shown in main project scree arrange themselves like out camera configuration once the project has been opened. Now the constellations need to be loaded. This can be done by going to File->Open and another pop up window will open. Navigate back to D:\Optitrack_Configuration (It should open to this directory by default) and select the most recently dated set of RADA trackables. They are named like RADA_entireSystem_M_D_YYYY.tra. The most recent one as of August 1st, 2016 is RADA_entireSystem_7_8_2016.tra.
[[Image:Opening_trackables.PNG|800px]]
Once the project and trackless are open the cameras should appear in their constellation (square) and there should be two constellations under Project Explorer->Trackables. One Named UAV for the pendulum and one named ERIS for the ground vehicle. In order to get additional information about each constellation left click on the the name of the desired trackable.
[[Image:SelectingUAV.PNG|800px]]
Once a trackable is selected more information about it is available in the Trackables Tab on the right side of the screen. For the current position and orientation look at the Real-Time Info sub -tab. This gives the orientation in the wrong order for how we currently use the Euler angles. When two or three of the angles are near zero you can switch yaw and pitch to get roughly the correct orientation.
[[Image:Uav_realTimeInfo.PNG|800px]]
Now we need check to make sure the system is zeroed.
1. Hold RADA so that the front of the ground robot (ERIS is facing the wall with the white boards (east)). The front side of Eris is labeled. If it isn't it is the side opposite of the switches and the side with the trackable constellation on it.
2. Make sure that the motor with the red motor mount is also facing the wall with the white boards.
3. Make sure the quad system is aligned along Eris Axis by standing behind the system and seeing if you can use the pole to block mounting bolts of the front propeller motor mount when looking at the pole while facing the east wall.
4. While holding the pendulum approximately vertical see if the camera system reads zeros for the pendulum (UAV) pitch and roll (yaw and roll in Real-Time Info). If yaw is off by a few degrees that is fine.
5. Compare the yaw of the UAV to that of ERIS (Remember this is pitch in REal-Time Info). If they are both near zero and with in a few degrees and the pendulum's pitch/roll were also near zero then you are ready to use the camera system. Otherwise go to the next step.
6. You need to zero the pendulum.
- Align ERIS so it is near zero yaw first (eye ball it).
- Get a level and a friend. Have your friend use a level to ensure that the pendulum is level in both directs and hold it there.
- With the UAV constellation selected go to the Orientation tab (next to Real-Time Info tab) and click on Reset To Current Orientation button
- Now your friend can set the pendulum down and you can zero ERIS the same way.
7. Save the new trackable orientation by going to File->Save Trakables... and save a file using the same naming conventions as the trackable file you opened earlier except use the current data so you don't have to re-zero the system the next time you test.
[[Image:Uav_ResetOrientation.PNG|800px]]
=== Building Software ===
The development environment for running RADA is hosted on CO3050-11, a Linux Red Hat environment. This computer has a local ucart user name that you should use. The password isn't put here for security reasons. In order to ensure that the RADA software is setup correctly for the test you want to run. To do this you will need to open the main.cpp and logger.cpp files and make sure all of the compile time macros you want are defined correctly. All of the c++ files you should need to edit are in the directory ~/Desktop/rada_research_project/ErisResearchCode/CppProjects/MainProgram_PacketLoss/src/Korebot Below is a compiler macro options for main.cpp:
-'''H2ctrl''' : This will cause the system to enter H2 controller mode where the whole RADA system is controlled by an H2 controller.
-'''ssTracking''' : H2ctrl must also be defined for this macro to do anything. This macro will has the system to be controlled by a tracking H2 controller.
-'''ssMotors''' : H2ctrl must also be defined for this macro to do anything. This macro will has the system to be controlled by an H2 contorller that contains propeller states. This also cause the system to "Dance."
-'''ssDrop''' : Cause the system to go into packet drop controller mode. This mode allows controllers designed for lossy networks to be tested. Based off of other definitions how lossy the network is can be simulated. If nothing else is defined this controller becomes basically a H2 controller.
-'''drop10''' : Will put the packet drop mode into 10% loss mode and use a controller designed for 10% loss.
-'''drop30''' : Will put the packet drop mode into 30% loss mode and use a controller designed for 30% loss.
-'''drop50''' : Will put the packet drop mode into 50% loss mode and use a controller designed for 50% loss.
-'''mot50''' : This macro over-rides all other macros. If this is turned on the wheels will not run and the propllers will be run at 50% command. This is used for measuring the effective battery voltage seen by the ESCs. This is always run after a test.
-'''RADAlqi''' : This macro will cause the system to use an LQI controller on the whole system. The linear velocity states are calculated with no filter and the angular velocity states are calculated with filters.
-'''RADAlqi_est''' : This macro will cause the system to use an LQI controller on the whole system. A traditional estimator is used to estimate the states.
-'''rada_lqg''' : This macro will cause the entire system to be controlled by a LQG controller/estimator system.
-'''rada_split_lqg''' : This macro will cause the pendulum and ground robot to be controlled by their own LQG systems.
-'''rada_split_lqg_ol''' : This macro will cause the pendulum to be controlled by an LQG controller, the yaw of the ground robot to be controlled by a PID controller, and the ground robot linear velocities to be controlled with open-loop commands.
-'''yaw_off''' : This macro will cause the yaw control to be disabled on some controllers.
*'''accR''' : This macro will cause the PID linear velocity controllers to be given ramps to acclerate from one velocity to another instead of steps.
-'''posRamp''' : This macro will cause the linear velocities of RADA to be controlled by position PIDs with ramp reference instead of velocity commands.
-If no controller selection is made all controllers revert to PID controllers
All of these macros can be defined simply by uncommenting the corresponding define statement in main.cpp. The macros in the logger.cpp can be seen below:
-'''ssDrop''' : This macro puts the logger into packed drop controller mode and logs the correct values for the packet drop controllers.
-'''RADAlqi''' : This macro puts the logger into full system LQI controller logging mode.
-'''RADAlqi_est''' : This macro puts the logger into full system LQI controller plus estimator logging mode.
-'''rada_lqg''' : This puts the logger into full system LQG controller logging mode.
-'''rada_split_lqg''' : This macro causes the logger to log data about the subsystem LQG controllers.
-'''rada_split_lqg_ol''' : This cause the system to log data about the pendulum LQG system and the open-loop linear velocity commands.
-'''H2ctrl''' : This macro causes the logger to log data about the full system H2 controllers.
-If no logging mode is selected then the logger will default to logging PID data.
Because the system only calculates controllers for one set of controllers it is important to ensure that the logger is in the correct mode based off of what is defined in main.cpp. As of August 1st, 2016 the defines in main.cpp are not seen in logger.cpp.
Finally in a command prompt navigate to the driectroy: ~/Desktop/rada_research_project/ErisResearchCode/CppProjects/MainProgram_PacketLoss
Here just type: make. The code will compile for your desired mode. For setting up a new development directory see [http://wikis.ece.iastate.edu/robotic-agriculture-data-acquisition/index.php/Setting_up_a_new_development_environment Setting up a new development environment] from the RADA senior Design wiki.
[[Image:ComplingRADACode.png|800px]]
The complied executable code ends up in /home/shared/MainProject. The /home/shared directory is setup as a network file share (NFS).
[[Image:ErisCompliedCode-config.png|800px]]
This service needs to be restarted when CO3050-11 is restarted. [http://wikis.ece.iastate.edu/robotic-agriculture-data-acquisition/index.php/Configuring_NFS_shares_for_the_robot Configure NFS shares for the robot] from the RADA Senior Design wiki. Be sure to use the new Linux install command in step six. Though I have fond that even on a good strt the ''[ok]'' messages will still print.
=== Turing on RADA ===
Turing on Eris is fairly simple. eAch system has its own battery. There is one for the wheels that plugs in at the front of Eris (opposite side of the swiches), one for the electronics in the back of Eris (in between the switches), and one for the propellers that goes on top of Eris.
[[Image:ErisOnPhoto.jpg|800px]]
The wheel battery is normally 1600 mAh 2-cell Lipo but any 2-cell Lipo will work. The wheels are turned on by flipping the silver switch so the top points away from the system. The electronics normally use a 2600 mAh 2-cell Lipo. The electronics are turned on by flipping the green switch away from the system. It is important that you only the WIFI adapter or Ethernet plugged in at the same time or VRPN my listen to the camera data broadcast over both connects which could cause problems.
=== Connecting to RADA ===
== Testing RADA ==
=== Running the first test after power up ===
=== Running additional tests ===
=== Measuring battery voltages ===
=== Locating and retrieving log files ===
== Post processing and Simulation ==
=== Using the MATLAB data parsing tool ===
=== Adding additional data for simulations ===
=== Setting up the MATLAB workspace for simulation ===
=== Running simulations and storing results ===
=== Plotting results ===
c257bb102eb98ed126090e8a0668a1463332c054
218
217
2016-08-02T02:11:20Z
Pfuhing
5
wikitext
text/x-wiki
This page will take you though setting up and testing RADA, retrieving the log file and other necessary data to run a simulation of that test and processing the data in MATLAB. Then actually running the simulation of RADA in Simulink.
== Setting Up a RADA Test ==
Testing RADA is not overly difficult once you get the hang of the steps to setup RADA. The following steps may seem like a long process to go from starting the testing process to having completed simulation and plotting of the test results but this whole test procedure (with the exception of battery charging) can be completed in about 15-20 minutes. These steps are meant to be as detailed as possible in order to help new users of RADA to get up and running as quickly as possible.
'''<span style="color:red">NOTE: Always run RADA with at least 2 people!</span>''' The pendulum arm can crash into the ground if the network starts to drop packets and one person cannot give commands to RADA and spot the pendulum. This is a safety issue for both you and the RADA platform.
=== Charging batteries ===
The lab currently uses mostly Hyperion batteries. We charge our batteries with a Hyperion EOS 1420i Net3 battery charger. For some general information about how to use this charger see [https://www.youtube.com/watch?v=-ox3EpzvsJ8 this video.]. In the lab we power this charger using the old Kepco Power supplu because it is the only power supply that we have that can supply enough current. Make sure that the power supply is set to an output voltage between 10.5V-29V.
{| class="wikitable" style="text-align:center"
|-
| [[Image:ChargerPowerSupplyOff.JPG|400px]]
| [[Image:ChargerPowerSuplyOn.JPG|400px]]
|-
| Kepco Power Supply off.
| Kepco Power Supply on with correct voltage supply range.
|}
While the YouTube video linked above should explain how to use the charger. Currently three different Lithium polymer batteries (Lipo): 1600 mAh 2-cell Lipo for the wheels, 2600 mAh 2-cell Lipo for the electronics of Eris, and a 2600 mAh 4-cell Lipo. The 1600 mAh 2-cell Lipo can be charged using memory slot 2 of the charger. The 2600 mAh 2-cell Lipos can be charged using memory slot 3 for fast charging and memory slot 4 for slower charging (use this if the battery gets run really low for 10-20 minutes then switch to fast charging). The 2600 mAh 4-cell Lipo can be charged using memory slot 8. The 1600 mAh 2-cell and 2600 mAr 4-cell generally charge in 10-20 minutes apiece while I generally fine it takes the 2600 mAh 2-cell up to 70 minutes to charge fully.
=== Setting up the camera system ===
The camera system is run on the windows computer CO3050-07. You can log into this computer using a local microcart username and password which is not posted here for security reasons but any one who works in the lab should know it. Once logged in look for Tracking Tools in the start menu or look for the shortcut shown below:
[[Image:TrackingTools_shortcut.PNG|thumb|center|Tracking Tools shortcut]]
Once the program opens the screen should look something like this:
[[Image:NewTrackingTools.PNG|800px]]
In the Tracking Tools Quick Start pop up menu select Open Existing Project and then navigate to D:\Optitrack_Configuration (It should open to this directory by default) and select the most recent Tracking Tools project. It should be named like TrackingToolsProject YYYY-MM-DD timeStamp.ttp. This is normally the most recently edited file when sorting by data modified. The most recent one as of August 1st, 2016 is TrackingToolsProject 2015-09-23 2.30pm.ttp.
[[Image:OpeningProject.PNG|800px]]
You should notice that the cameras shown in main project scree arrange themselves like out camera configuration once the project has been opened. Now the constellations need to be loaded. This can be done by going to File->Open and another pop up window will open. Navigate back to D:\Optitrack_Configuration (It should open to this directory by default) and select the most recently dated set of RADA trackables. They are named like RADA_entireSystem_M_D_YYYY.tra. The most recent one as of August 1st, 2016 is RADA_entireSystem_7_8_2016.tra.
[[Image:Opening_trackables.PNG|800px]]
Once the project and trackless are open the cameras should appear in their constellation (square) and there should be two constellations under Project Explorer->Trackables. One Named UAV for the pendulum and one named ERIS for the ground vehicle. In order to get additional information about each constellation left click on the the name of the desired trackable.
[[Image:SelectingUAV.PNG|800px]]
Once a trackable is selected more information about it is available in the Trackables Tab on the right side of the screen. For the current position and orientation look at the Real-Time Info sub -tab. This gives the orientation in the wrong order for how we currently use the Euler angles. When two or three of the angles are near zero you can switch yaw and pitch to get roughly the correct orientation.
[[Image:Uav_realTimeInfo.PNG|800px]]
Now we need check to make sure the system is zeroed.
1. Hold RADA so that the front of the ground robot (ERIS is facing the wall with the white boards (east)). The front side of Eris is labeled. If it isn't it is the side opposite of the switches and the side with the trackable constellation on it.
2. Make sure that the motor with the red motor mount is also facing the wall with the white boards.
3. Make sure the quad system is aligned along Eris Axis by standing behind the system and seeing if you can use the pole to block mounting bolts of the front propeller motor mount when looking at the pole while facing the east wall.
4. While holding the pendulum approximately vertical see if the camera system reads zeros for the pendulum (UAV) pitch and roll (yaw and roll in Real-Time Info). If yaw is off by a few degrees that is fine.
5. Compare the yaw of the UAV to that of ERIS (Remember this is pitch in REal-Time Info). If they are both near zero and with in a few degrees and the pendulum's pitch/roll were also near zero then you are ready to use the camera system. Otherwise go to the next step.
6. You need to zero the pendulum.
- Align ERIS so it is near zero yaw first (eye ball it).
- Get a level and a friend. Have your friend use a level to ensure that the pendulum is level in both directs and hold it there.
- With the UAV constellation selected go to the Orientation tab (next to Real-Time Info tab) and click on Reset To Current Orientation button
- Now your friend can set the pendulum down and you can zero ERIS the same way.
7. Save the new trackable orientation by going to File->Save Trakables... and save a file using the same naming conventions as the trackable file you opened earlier except use the current data so you don't have to re-zero the system the next time you test.
[[Image:Uav_ResetOrientation.PNG|800px]]
=== Building Software ===
The development environment for running RADA is hosted on CO3050-11, a Linux Red Hat environment. This computer has a local ucart user name that you should use. The password isn't put here for security reasons. In order to ensure that the RADA software is setup correctly for the test you want to run. To do this you will need to open the main.cpp and logger.cpp files and make sure all of the compile time macros you want are defined correctly. All of the c++ files you should need to edit are in the directory ~/Desktop/rada_research_project/ErisResearchCode/CppProjects/MainProgram_PacketLoss/src/Korebot Below is a compiler macro options for main.cpp:
-'''H2ctrl''' : This will cause the system to enter H2 controller mode where the whole RADA system is controlled by an H2 controller.
-'''ssTracking''' : H2ctrl must also be defined for this macro to do anything. This macro will has the system to be controlled by a tracking H2 controller.
-'''ssMotors''' : H2ctrl must also be defined for this macro to do anything. This macro will has the system to be controlled by an H2 contorller that contains propeller states. This also cause the system to "Dance."
-'''ssDrop''' : Cause the system to go into packet drop controller mode. This mode allows controllers designed for lossy networks to be tested. Based off of other definitions how lossy the network is can be simulated. If nothing else is defined this controller becomes basically a H2 controller.
-'''drop10''' : Will put the packet drop mode into 10% loss mode and use a controller designed for 10% loss.
-'''drop30''' : Will put the packet drop mode into 30% loss mode and use a controller designed for 30% loss.
-'''drop50''' : Will put the packet drop mode into 50% loss mode and use a controller designed for 50% loss.
-'''mot50''' : This macro over-rides all other macros. If this is turned on the wheels will not run and the propllers will be run at 50% command. This is used for measuring the effective battery voltage seen by the ESCs. This is always run after a test.
-'''RADAlqi''' : This macro will cause the system to use an LQI controller on the whole system. The linear velocity states are calculated with no filter and the angular velocity states are calculated with filters.
-'''RADAlqi_est''' : This macro will cause the system to use an LQI controller on the whole system. A traditional estimator is used to estimate the states.
-'''rada_lqg''' : This macro will cause the entire system to be controlled by a LQG controller/estimator system.
-'''rada_split_lqg''' : This macro will cause the pendulum and ground robot to be controlled by their own LQG systems.
-'''rada_split_lqg_ol''' : This macro will cause the pendulum to be controlled by an LQG controller, the yaw of the ground robot to be controlled by a PID controller, and the ground robot linear velocities to be controlled with open-loop commands.
-'''yaw_off''' : This macro will cause the yaw control to be disabled on some controllers.
*'''accR''' : This macro will cause the PID linear velocity controllers to be given ramps to acclerate from one velocity to another instead of steps.
-'''posRamp''' : This macro will cause the linear velocities of RADA to be controlled by position PIDs with ramp reference instead of velocity commands.
-If no controller selection is made all controllers revert to PID controllers
All of these macros can be defined simply by uncommenting the corresponding define statement in main.cpp. The macros in the logger.cpp can be seen below:
-'''ssDrop''' : This macro puts the logger into packed drop controller mode and logs the correct values for the packet drop controllers.
-'''RADAlqi''' : This macro puts the logger into full system LQI controller logging mode.
-'''RADAlqi_est''' : This macro puts the logger into full system LQI controller plus estimator logging mode.
-'''rada_lqg''' : This puts the logger into full system LQG controller logging mode.
-'''rada_split_lqg''' : This macro causes the logger to log data about the subsystem LQG controllers.
-'''rada_split_lqg_ol''' : This cause the system to log data about the pendulum LQG system and the open-loop linear velocity commands.
-'''H2ctrl''' : This macro causes the logger to log data about the full system H2 controllers.
-If no logging mode is selected then the logger will default to logging PID data.
Because the system only calculates controllers for one set of controllers it is important to ensure that the logger is in the correct mode based off of what is defined in main.cpp. As of August 1st, 2016 the defines in main.cpp are not seen in logger.cpp.
Finally in a command prompt navigate to the driectroy: ~/Desktop/rada_research_project/ErisResearchCode/CppProjects/MainProgram_PacketLoss
Here just type: make. The code will compile for your desired mode. For setting up a new development directory see [http://wikis.ece.iastate.edu/robotic-agriculture-data-acquisition/index.php/Setting_up_a_new_development_environment Setting up a new development environment] from the RADA senior Design wiki.
[[Image:ComplingRADACode.png|800px]]
The complied executable code ends up in /home/shared/MainProject. The /home/shared directory is setup as a network file share (NFS).
[[Image:ErisCompliedCode-config.png|800px]]
This service needs to be restarted when CO3050-11 is restarted. [http://wikis.ece.iastate.edu/robotic-agriculture-data-acquisition/index.php/Configuring_NFS_shares_for_the_robot Configure NFS shares for the robot] from the RADA Senior Design wiki. Be sure to use the new Linux install command in step six. Though I have fond that even on a good strt the ''[ok]'' messages will still print.
=== Turing on RADA ===
Turing on Eris is fairly simple. Each system has its own battery. There is one for the wheels that plugs in at the front of Eris (opposite side of the swiches), one for the electronics in the back of Eris (in between the switches), and one for the propellers that goes on top of Eris.
[[Image:ErisOnPhoto.jpg|800px]]
The wheel battery is normally 1600 mAh 2-cell Lipo but any 2-cell Lipo will work. The wheels are turned on by flipping the silver switch so the top points away from the system. The electronics normally use a 2600 mAh 2-cell Lipo. The electronics are turned on by flipping the green switch away from the system. It is important that you only the WIFI adapter or Ethernet plugged in at the same time or VRPN my listen to the camera data broadcast over both connects which could cause problems. The propeller system is powered via a 2600 mAh 4-cell Lipo that connects to a power cable at the base of the pendulum. There is a switch to turn on the power to the propellers system. You will know it is on when the 1 on the switch is flush with the switch housing instead of sticking out. It takes about 30 seconds to a minute for Eris to boot up and start the networking connections. When the WIFI is plugged in you will know it is ready when a blue light turns on, on the module.
=== Connecting to RADA ===
== Testing RADA ==
=== Running the first test after power up ===
=== Running additional tests ===
=== Measuring battery voltages ===
=== Locating and retrieving log files ===
== Post processing and Simulation ==
=== Using the MATLAB data parsing tool ===
=== Adding additional data for simulations ===
=== Setting up the MATLAB workspace for simulation ===
=== Running simulations and storing results ===
=== Plotting results ===
e619274a8603ea6767bb1b14f5f13db70a53e533
221
218
2016-08-02T02:22:17Z
Pfuhing
5
wikitext
text/x-wiki
This page will take you though setting up and testing RADA, retrieving the log file and other necessary data to run a simulation of that test and processing the data in MATLAB. Then actually running the simulation of RADA in Simulink.
== Setting Up a RADA Test ==
Testing RADA is not overly difficult once you get the hang of the steps to setup RADA. The following steps may seem like a long process to go from starting the testing process to having completed simulation and plotting of the test results but this whole test procedure (with the exception of battery charging) can be completed in about 15-20 minutes. These steps are meant to be as detailed as possible in order to help new users of RADA to get up and running as quickly as possible.
'''<span style="color:red">NOTE: Always run RADA with at least 2 people!</span>''' The pendulum arm can crash into the ground if the network starts to drop packets and one person cannot give commands to RADA and spot the pendulum. This is a safety issue for both you and the RADA platform.
=== Charging batteries ===
The lab currently uses mostly Hyperion batteries. We charge our batteries with a Hyperion EOS 1420i Net3 battery charger. For some general information about how to use this charger see [https://www.youtube.com/watch?v=-ox3EpzvsJ8 this video.]. In the lab we power this charger using the old Kepco Power supplu because it is the only power supply that we have that can supply enough current. Make sure that the power supply is set to an output voltage between 10.5V-29V.
{| class="wikitable" style="text-align:center"
|-
| [[Image:ChargerPowerSupplyOff.JPG|400px]]
| [[Image:ChargerPowerSuplyOn.JPG|400px]]
|-
| Kepco Power Supply off.
| Kepco Power Supply on with correct voltage supply range.
|}
While the YouTube video linked above should explain how to use the charger. Currently three different Lithium polymer batteries (Lipo): 1600 mAh 2-cell Lipo for the wheels, 2600 mAh 2-cell Lipo for the electronics of Eris, and a 2600 mAh 4-cell Lipo. The 1600 mAh 2-cell Lipo can be charged using memory slot 2 of the charger. The 2600 mAh 2-cell Lipos can be charged using memory slot 3 for fast charging and memory slot 4 for slower charging (use this if the battery gets run really low for 10-20 minutes then switch to fast charging). The 2600 mAh 4-cell Lipo can be charged using memory slot 8. The 1600 mAh 2-cell and 2600 mAr 4-cell generally charge in 10-20 minutes apiece while I generally fine it takes the 2600 mAh 2-cell up to 70 minutes to charge fully.
=== Setting up the camera system ===
The camera system is run on the windows computer CO3050-07. You can log into this computer using a local microcart username and password which is not posted here for security reasons but any one who works in the lab should know it. Once logged in look for Tracking Tools in the start menu or look for the shortcut shown below:
[[Image:TrackingTools_shortcut.PNG|thumb|center|Tracking Tools shortcut]]
Once the program opens the screen should look something like this:
[[Image:NewTrackingTools.PNG|800px]]
In the Tracking Tools Quick Start pop up menu select Open Existing Project and then navigate to ''D:\Optitrack_Configuration'' (It should open to this directory by default) and select the most recent Tracking Tools project. It should be named like ''TrackingToolsProject YYYY-MM-DD timeStamp.ttp''. This is normally the most recently edited file when sorting by data modified. The most recent one as of August 1st, 2016 is ''TrackingToolsProject 2015-09-23 2.30pm.ttp''.
[[Image:OpeningProject.PNG|800px]]
You should notice that the cameras shown in main project scree arrange themselves like out camera configuration once the project has been opened. Now the constellations need to be loaded. This can be done by going to ''File->Open'' and another pop up window will open. Navigate back to ''D:\Optitrack_Configuration'' (It should open to this directory by default) and select the most recently dated set of RADA trackables. They are named like ''RADA_entireSystem_M_D_YYYY.tra''. The most recent one as of August 1st, 2016 is ''RADA_entireSystem_7_8_2016.tra''.
[[Image:Opening_trackables.PNG|800px]]
Once the project and trackless are open the cameras should appear in their constellation (square) and there should be two constellations under ''Project Explorer->Trackables''. One Named UAV for the pendulum and one named ERIS for the ground vehicle. In order to get additional information about each constellation left click on the the name of the desired trackable.
[[Image:SelectingUAV.PNG|800px]]
Once a trackable is selected more information about it is available in the ''Trackables'' Tab on the right side of the screen. For the current position and orientation look at the ''Real-Time Info'' sub-tab. This gives the orientation in the wrong order for how we currently use the Euler angles. When two or three of the angles are near zero you can switch yaw and pitch to get roughly the correct orientation.
[[Image:Uav_realTimeInfo.PNG|800px]]
Now we need check to make sure the system is zeroed.
1. Hold RADA so that the front of the ground robot (ERIS is facing the wall with the white boards (east)). The front side of Eris is labeled. If it isn't it is the side opposite of the switches and the side with the trackable constellation on it.
2. Make sure that the motor with the red motor mount is also facing the wall with the white boards.
3. Make sure the quad system is aligned along Eris Axis by standing behind the system and seeing if you can use the pole to block mounting bolts of the front propeller motor mount when looking at the pole while facing the east wall.
4. While holding the pendulum approximately vertical see if the camera system reads zeros for the pendulum (UAV) pitch and roll (yaw and roll in ''Real-Time Info''). If yaw is off by a few degrees that is fine.
5. Compare the yaw of the UAV to that of ERIS (Remember this is pitch in ''Real-Time Info''). If they are both near zero and with in a few degrees and the pendulum's pitch/roll were also near zero then you are ready to use the camera system. Otherwise go to the next step.
6. You need to zero the pendulum.
- Align ERIS so it is near zero yaw first (eye ball it).
- Get a level and a friend. Have your friend use a level to ensure that the pendulum is level in both directs and hold it there.
- With the UAV constellation selected go to the ''Orientation'' tab (next to ''Real-Time Info'' tab) and click on ''Reset To Current Orientation button''
- Now your friend can set the pendulum down and you can zero ERIS the same way.
7. Save the new trackable orientation by going to ''File->Save Trakables...'' and save a file using the same naming conventions as the trackable file you opened earlier except use the current data so you don't have to re-zero the system the next time you test.
[[Image:Uav_ResetOrientation.PNG|800px]]
=== Building Software ===
The development environment for running RADA is hosted on CO3050-11, a Linux Red Hat environment. This computer has a local ucart user name that you should use. The password isn't put here for security reasons. In order to ensure that the RADA software is setup correctly for the test you want to run. To do this you will need to open the main.cpp and logger.cpp files and make sure all of the compile time macros you want are defined correctly. All of the c++ files you should need to edit are in the directory ''~/Desktop/rada_research_project/ErisResearchCode/CppProjects/MainProgram_PacketLoss/src/Korebot'' Below is a compiler macro options for main.cpp:
-'''H2ctrl''' : This will cause the system to enter H2 controller mode where the whole RADA system is controlled by an H2 controller.
-'''ssTracking''' : H2ctrl must also be defined for this macro to do anything. This macro will has the system to be controlled by a tracking H2 controller.
-'''ssMotors''' : H2ctrl must also be defined for this macro to do anything. This macro will has the system to be controlled by an H2 contorller that contains propeller states. This also cause the system to "Dance."
-'''ssDrop''' : Cause the system to go into packet drop controller mode. This mode allows controllers designed for lossy networks to be tested. Based off of other definitions how lossy the network is can be simulated. If nothing else is defined this controller becomes basically a H2 controller.
-'''drop10''' : Will put the packet drop mode into 10% loss mode and use a controller designed for 10% loss.
-'''drop30''' : Will put the packet drop mode into 30% loss mode and use a controller designed for 30% loss.
-'''drop50''' : Will put the packet drop mode into 50% loss mode and use a controller designed for 50% loss.
-'''mot50''' : This macro over-rides all other macros. If this is turned on the wheels will not run and the propllers will be run at 50% command. This is used for measuring the effective battery voltage seen by the ESCs. This is always run after a test.
-'''RADAlqi''' : This macro will cause the system to use an LQI controller on the whole system. The linear velocity states are calculated with no filter and the angular velocity states are calculated with filters.
-'''RADAlqi_est''' : This macro will cause the system to use an LQI controller on the whole system. A traditional estimator is used to estimate the states.
-'''rada_lqg''' : This macro will cause the entire system to be controlled by a LQG controller/estimator system.
-'''rada_split_lqg''' : This macro will cause the pendulum and ground robot to be controlled by their own LQG systems.
-'''rada_split_lqg_ol''' : This macro will cause the pendulum to be controlled by an LQG controller, the yaw of the ground robot to be controlled by a PID controller, and the ground robot linear velocities to be controlled with open-loop commands.
-'''yaw_off''' : This macro will cause the yaw control to be disabled on some controllers.
*'''accR''' : This macro will cause the PID linear velocity controllers to be given ramps to acclerate from one velocity to another instead of steps.
-'''posRamp''' : This macro will cause the linear velocities of RADA to be controlled by position PIDs with ramp reference instead of velocity commands.
-If no controller selection is made all controllers revert to PID controllers
All of these macros can be defined simply by uncommenting the corresponding define statement in main.cpp. The macros in the logger.cpp can be seen below:
-'''ssDrop''' : This macro puts the logger into packed drop controller mode and logs the correct values for the packet drop controllers.
-'''RADAlqi''' : This macro puts the logger into full system LQI controller logging mode.
-'''RADAlqi_est''' : This macro puts the logger into full system LQI controller plus estimator logging mode.
-'''rada_lqg''' : This puts the logger into full system LQG controller logging mode.
-'''rada_split_lqg''' : This macro causes the logger to log data about the subsystem LQG controllers.
-'''rada_split_lqg_ol''' : This cause the system to log data about the pendulum LQG system and the open-loop linear velocity commands.
-'''H2ctrl''' : This macro causes the logger to log data about the full system H2 controllers.
-If no logging mode is selected then the logger will default to logging PID data.
Because the system only calculates controllers for one set of controllers it is important to ensure that the logger is in the correct mode based off of what is defined in main.cpp. As of August 1st, 2016 the defines in main.cpp are not seen in logger.cpp.
Finally in a command prompt navigate to the driectroy: ''~/Desktop/rada_research_project/ErisResearchCode/CppProjects/MainProgram_PacketLoss''
Here just type: ''make''. The code will compile for your desired mode. For setting up a new development directory see [http://wikis.ece.iastate.edu/robotic-agriculture-data-acquisition/index.php/Setting_up_a_new_development_environment Setting up a new development environment] from the RADA senior Design wiki.
[[Image:ComplingRADACode.png|800px]]
The complied executable code ends up in ''/home/shared/MainProject''. The ''/home/shared'' directory is setup as a network file share (NFS).
[[Image:ErisCompliedCode-config.png|800px]]
This service needs to be restarted when CO3050-11 is restarted. [http://wikis.ece.iastate.edu/robotic-agriculture-data-acquisition/index.php/Configuring_NFS_shares_for_the_robot Configure NFS shares for the robot] from the RADA Senior Design wiki. Be sure to use the new Linux install command in step six. Though I have fond that even on a good strt the ''[ok]'' messages will still print.
=== Turing on RADA ===
Turing on Eris is fairly simple. Each system has its own battery. There is one for the wheels that plugs in at the front of Eris (opposite side of the swiches), one for the electronics in the back of Eris (in between the switches), and one for the propellers that goes on top of Eris.
[[Image:ErisOnPhoto.jpg|800px]]
The wheel battery is normally 1600 mAh 2-cell Lipo but any 2-cell Lipo will work. The wheels are turned on by flipping the silver switch so the top points away from the system. The electronics normally use a 2600 mAh 2-cell Lipo. The electronics are turned on by flipping the green switch away from the system. It is important that you only the WIFI adapter or Ethernet plugged in at the same time or VRPN my listen to the camera data broadcast over both connects which could cause problems. The propeller system is powered via a 2600 mAh 4-cell Lipo that connects to a power cable at the base of the pendulum. There is a switch to turn on the power to the propellers system. You will know it is on when the 1 on the switch is flush with the switch housing instead of sticking out. It takes about 30 seconds to a minute for Eris to boot up and start the networking connections. When the WIFI is plugged in you will know it is ready when a blue light turns on, on the module.
=== Connecting to RADA ===
RADA is controlled through an SSH connection. in a commands prompt, not the one you compile the code from so that you can recompile for different setup with out needing to close the connection. If you are using a WIFI connect use the command ''ssh root@192.168.0.53''
== Testing RADA ==
=== Running the first test after power up ===
=== Running additional tests ===
=== Locating and retrieving log files ===
=== Measuring battery voltages ===
== Post processing and Simulation ==
=== Using the MATLAB data parsing tool ===
=== Adding additional data for simulations ===
=== Setting up the MATLAB workspace for simulation ===
=== Running simulations and storing results ===
=== Plotting results ===
5616f1d64ec4a8ab70af727eaf6787dd052ff6da
222
221
2016-08-02T02:26:06Z
Pfuhing
5
wikitext
text/x-wiki
This page will take you though setting up and testing RADA, retrieving the log file and other necessary data to run a simulation of that test and processing the data in MATLAB. Then actually running the simulation of RADA in Simulink.
== Setting Up a RADA Test ==
Testing RADA is not overly difficult once you get the hang of the steps to setup RADA. The following steps may seem like a long process to go from starting the testing process to having completed simulation and plotting of the test results but this whole test procedure (with the exception of battery charging) can be completed in about 15-20 minutes. These steps are meant to be as detailed as possible in order to help new users of RADA to get up and running as quickly as possible.
'''<span style="color:red">NOTE: Always run RADA with at least 2 people!</span>''' The pendulum arm can crash into the ground if the network starts to drop packets and one person cannot give commands to RADA and spot the pendulum. This is a safety issue for both you and the RADA platform.
=== Charging batteries ===
The lab currently uses mostly Hyperion batteries. We charge our batteries with a Hyperion EOS 1420i Net3 battery charger. For some general information about how to use this charger see [https://www.youtube.com/watch?v=-ox3EpzvsJ8 this video.]. In the lab we power this charger using the old Kepco Power supplu because it is the only power supply that we have that can supply enough current. Make sure that the power supply is set to an output voltage between 10.5V-29V.
{| class="wikitable" style="text-align:center"
|-
| [[Image:ChargerPowerSupplyOff.JPG|400px]]
| [[Image:ChargerPowerSuplyOn.JPG|400px]]
|-
| Kepco Power Supply off.
| Kepco Power Supply on with correct voltage supply range.
|}
While the YouTube video linked above should explain how to use the charger. Currently three different Lithium polymer batteries (Lipo): 1600 mAh 2-cell Lipo for the wheels, 2600 mAh 2-cell Lipo for the electronics of Eris, and a 2600 mAh 4-cell Lipo. The 1600 mAh 2-cell Lipo can be charged using memory slot 2 of the charger. The 2600 mAh 2-cell Lipos can be charged using memory slot 3 for fast charging and memory slot 4 for slower charging (use this if the battery gets run really low for 10-20 minutes then switch to fast charging). The 2600 mAh 4-cell Lipo can be charged using memory slot 8. The 1600 mAh 2-cell and 2600 mAr 4-cell generally charge in 10-20 minutes apiece while I generally fine it takes the 2600 mAh 2-cell up to 70 minutes to charge fully.
=== Setting up the camera system ===
The camera system is run on the windows computer CO3050-07. You can log into this computer using a local microcart username and password which is not posted here for security reasons but any one who works in the lab should know it. Once logged in look for Tracking Tools in the start menu or look for the shortcut shown below:
[[Image:TrackingTools_shortcut.PNG|thumb|center|Tracking Tools shortcut]]
Once the program opens the screen should look something like this:
[[Image:NewTrackingTools.PNG|800px]]
In the Tracking Tools Quick Start pop up menu select Open Existing Project and then navigate to ''D:\Optitrack_Configuration'' (It should open to this directory by default) and select the most recent Tracking Tools project. It should be named like ''TrackingToolsProject YYYY-MM-DD timeStamp.ttp''. This is normally the most recently edited file when sorting by data modified. The most recent one as of August 1st, 2016 is ''TrackingToolsProject 2015-09-23 2.30pm.ttp''.
[[Image:OpeningProject.PNG|800px]]
You should notice that the cameras shown in main project scree arrange themselves like out camera configuration once the project has been opened. Now the constellations need to be loaded. This can be done by going to ''File->Open'' and another pop up window will open. Navigate back to ''D:\Optitrack_Configuration'' (It should open to this directory by default) and select the most recently dated set of RADA trackables. They are named like ''RADA_entireSystem_M_D_YYYY.tra''. The most recent one as of August 1st, 2016 is ''RADA_entireSystem_7_8_2016.tra''.
[[Image:Opening_trackables.PNG|800px]]
Once the project and trackless are open the cameras should appear in their constellation (square) and there should be two constellations under ''Project Explorer->Trackables''. One Named UAV for the pendulum and one named ERIS for the ground vehicle. In order to get additional information about each constellation left click on the the name of the desired trackable.
[[Image:SelectingUAV.PNG|800px]]
Once a trackable is selected more information about it is available in the ''Trackables'' Tab on the right side of the screen. For the current position and orientation look at the ''Real-Time Info'' sub-tab. This gives the orientation in the wrong order for how we currently use the Euler angles. When two or three of the angles are near zero you can switch yaw and pitch to get roughly the correct orientation.
[[Image:Uav_realTimeInfo.PNG|800px]]
Now we need check to make sure the system is zeroed.
1. Hold RADA so that the front of the ground robot (ERIS is facing the wall with the white boards (east)). The front side of Eris is labeled. If it isn't it is the side opposite of the switches and the side with the trackable constellation on it.
2. Make sure that the motor with the red motor mount is also facing the wall with the white boards.
3. Make sure the quad system is aligned along Eris Axis by standing behind the system and seeing if you can use the pole to block mounting bolts of the front propeller motor mount when looking at the pole while facing the east wall.
4. While holding the pendulum approximately vertical see if the camera system reads zeros for the pendulum (UAV) pitch and roll (yaw and roll in ''Real-Time Info''). If yaw is off by a few degrees that is fine.
5. Compare the yaw of the UAV to that of ERIS (Remember this is pitch in ''Real-Time Info''). If they are both near zero and with in a few degrees and the pendulum's pitch/roll were also near zero then you are ready to use the camera system. Otherwise go to the next step.
6. You need to zero the pendulum.
- Align ERIS so it is near zero yaw first (eye ball it).
- Get a level and a friend. Have your friend use a level to ensure that the pendulum is level in both directs and hold it there.
- With the UAV constellation selected go to the ''Orientation'' tab (next to ''Real-Time Info'' tab) and click on ''Reset To Current Orientation button''
- Now your friend can set the pendulum down and you can zero ERIS the same way.
7. Save the new trackable orientation by going to ''File->Save Trakables...'' and save a file using the same naming conventions as the trackable file you opened earlier except use the current data so you don't have to re-zero the system the next time you test.
[[Image:Uav_ResetOrientation.PNG|800px]]
=== Building Software ===
The development environment for running RADA is hosted on CO3050-11, a Linux Red Hat environment. This computer has a local ucart user name that you should use. The password isn't put here for security reasons. In order to ensure that the RADA software is setup correctly for the test you want to run. To do this you will need to open the main.cpp and logger.cpp files and make sure all of the compile time macros you want are defined correctly. All of the c++ files you should need to edit are in the directory ''~/Desktop/rada_research_project/ErisResearchCode/CppProjects/MainProgram_PacketLoss/src/Korebot'' Below is a compiler macro options for main.cpp:
-'''H2ctrl''' : This will cause the system to enter H2 controller mode where the whole RADA system is controlled by an H2 controller.
-'''ssTracking''' : H2ctrl must also be defined for this macro to do anything. This macro will has the system to be controlled by a tracking H2 controller.
-'''ssMotors''' : H2ctrl must also be defined for this macro to do anything. This macro will has the system to be controlled by an H2 contorller that contains propeller states. This also cause the system to "Dance."
-'''ssDrop''' : Cause the system to go into packet drop controller mode. This mode allows controllers designed for lossy networks to be tested. Based off of other definitions how lossy the network is can be simulated. If nothing else is defined this controller becomes basically a H2 controller.
-'''drop10''' : Will put the packet drop mode into 10% loss mode and use a controller designed for 10% loss.
-'''drop30''' : Will put the packet drop mode into 30% loss mode and use a controller designed for 30% loss.
-'''drop50''' : Will put the packet drop mode into 50% loss mode and use a controller designed for 50% loss.
-'''mot50''' : This macro over-rides all other macros. If this is turned on the wheels will not run and the propllers will be run at 50% command. This is used for measuring the effective battery voltage seen by the ESCs. This is always run after a test.
-'''RADAlqi''' : This macro will cause the system to use an LQI controller on the whole system. The linear velocity states are calculated with no filter and the angular velocity states are calculated with filters.
-'''RADAlqi_est''' : This macro will cause the system to use an LQI controller on the whole system. A traditional estimator is used to estimate the states.
-'''rada_lqg''' : This macro will cause the entire system to be controlled by a LQG controller/estimator system.
-'''rada_split_lqg''' : This macro will cause the pendulum and ground robot to be controlled by their own LQG systems.
-'''rada_split_lqg_ol''' : This macro will cause the pendulum to be controlled by an LQG controller, the yaw of the ground robot to be controlled by a PID controller, and the ground robot linear velocities to be controlled with open-loop commands.
-'''yaw_off''' : This macro will cause the yaw control to be disabled on some controllers.
*'''accR''' : This macro will cause the PID linear velocity controllers to be given ramps to acclerate from one velocity to another instead of steps.
-'''posRamp''' : This macro will cause the linear velocities of RADA to be controlled by position PIDs with ramp reference instead of velocity commands.
-If no controller selection is made all controllers revert to PID controllers
All of these macros can be defined simply by uncommenting the corresponding define statement in main.cpp. The macros in the logger.cpp can be seen below:
-'''ssDrop''' : This macro puts the logger into packed drop controller mode and logs the correct values for the packet drop controllers.
-'''RADAlqi''' : This macro puts the logger into full system LQI controller logging mode.
-'''RADAlqi_est''' : This macro puts the logger into full system LQI controller plus estimator logging mode.
-'''rada_lqg''' : This puts the logger into full system LQG controller logging mode.
-'''rada_split_lqg''' : This macro causes the logger to log data about the subsystem LQG controllers.
-'''rada_split_lqg_ol''' : This cause the system to log data about the pendulum LQG system and the open-loop linear velocity commands.
-'''H2ctrl''' : This macro causes the logger to log data about the full system H2 controllers.
-If no logging mode is selected then the logger will default to logging PID data.
Because the system only calculates controllers for one set of controllers it is important to ensure that the logger is in the correct mode based off of what is defined in main.cpp. As of August 1st, 2016 the defines in main.cpp are not seen in logger.cpp.
Finally in a command prompt navigate to the driectroy: ''~/Desktop/rada_research_project/ErisResearchCode/CppProjects/MainProgram_PacketLoss''
Here just type: ''make''. The code will compile for your desired mode. For setting up a new development directory see [http://wikis.ece.iastate.edu/robotic-agriculture-data-acquisition/index.php/Setting_up_a_new_development_environment Setting up a new development environment] from the RADA senior Design wiki.
[[Image:ComplingRADACode.png|800px]]
The complied executable code ends up in ''/home/shared/MainProject''. The ''/home/shared'' directory is setup as a network file share (NFS).
[[Image:ErisCompliedCode-config.png|800px]]
This service needs to be restarted when CO3050-11 is restarted. [http://wikis.ece.iastate.edu/robotic-agriculture-data-acquisition/index.php/Configuring_NFS_shares_for_the_robot Configure NFS shares for the robot] from the RADA Senior Design wiki. Be sure to use the new Linux install command in step six. Though I have fond that even on a good strt the ''[ok]'' messages will still print.
=== Turing on RADA ===
Turing on Eris is fairly simple. Each system has its own battery. There is one for the wheels that plugs in at the front of Eris (opposite side of the swiches), one for the electronics in the back of Eris (in between the switches), and one for the propellers that goes on top of Eris.
[[Image:ErisOnPhoto.jpg|800px]]
The wheel battery is normally 1600 mAh 2-cell Lipo but any 2-cell Lipo will work. The wheels are turned on by flipping the silver switch so the top points away from the system. The electronics normally use a 2600 mAh 2-cell Lipo. The electronics are turned on by flipping the green switch away from the system. It is important that you only the WIFI adapter or Ethernet plugged in at the same time or VRPN my listen to the camera data broadcast over both connects which could cause problems. The propeller system is powered via a 2600 mAh 4-cell Lipo that connects to a power cable at the base of the pendulum. There is a switch to turn on the power to the propellers system. You will know it is on when the 1 on the switch is flush with the switch housing instead of sticking out. It takes about 30 seconds to a minute for Eris to boot up and start the networking connections. When the WIFI is plugged in you will know it is ready when a blue light turns on, on the module.
=== Connecting to RADA ===
RADA is controlled through an SSH connection. in a commands prompt, not the one you compile the code from so that you can recompile for different setup with out needing to close the connection. If you are using a WIFI connect use the command ''ssh root@192.168.0.53''. If you are connected to Eris through a LAN connaction use the command ''ssh root@192.168.0.54''. If the connection goes though you should be proped for a password.
The password is ''rootme''.
[[Image:Ssh2Eris.png|800px]]
It is important to close the SSH connection before turning off Eris because the terminal you are using will hang up if you don't. You can close the connection by using the command ''exit''.
[[Image:ClosingSSH.png|800px]]
== Testing RADA ==
=== Running the first test after power up ===
=== Running additional tests ===
=== Locating and retrieving log files ===
=== Measuring battery voltages ===
== Post processing and Simulation ==
=== Using the MATLAB data parsing tool ===
=== Adding additional data for simulations ===
=== Setting up the MATLAB workspace for simulation ===
=== Running simulations and storing results ===
=== Plotting results ===
69a4958246e715106983757dbd59d35aafee3b17
225
222
2016-08-02T16:57:32Z
Pfuhing
5
/* Setting Up a RADA Test */
wikitext
text/x-wiki
This page will take you though setting up and testing RADA, retrieving the log file and other necessary data to run a simulation of that test and processing the data in MATLAB. Then actually running the simulation of RADA in Simulink.
== Setting Up a RADA Test ==
Testing RADA is not overly difficult once you get the hang of the steps to setup RADA. The following steps may seem like a long process to go from starting the testing process to having completed simulation and plotting of the test results but this whole test procedure (with the exception of battery charging) can be completed in about 15-20 minutes. These steps are meant to be as detailed as possible in order to help new users of RADA to get up and running as quickly as possible.
'''<span style="color:red">NOTE: Always run RADA with at least 2 people!</span>''' The pendulum arm can crash into the ground if the network starts to drop packets and one person cannot give commands to RADA and spot the pendulum. This is a safety issue for both you and the RADA platform.
=== Charging batteries ===
The lab currently uses mostly Hyperion batteries. We charge our batteries with a Hyperion EOS 1420i Net3 battery charger. For some general information about how to use this charger see [https://www.youtube.com/watch?v=-ox3EpzvsJ8 this video.]. In the lab we power this charger using the old Kepco Power supplu because it is the only power supply that we have that can supply enough current. Make sure that the power supply is set to an output voltage between 10.5V-29V.
{| class="wikitable" style="text-align:center"
|-
| [[Image:ChargerPowerSupplyOff.JPG|400px]]
| [[Image:ChargerPowerSuplyOn.JPG|400px]]
|-
| Kepco Power Supply off.
| Kepco Power Supply on with correct voltage supply range.
|}
While the YouTube video linked above should explain how to use the charger. Currently three different Lithium polymer batteries (Lipo): 1600 mAh 2-cell Lipo for the wheels, 2600 mAh 2-cell Lipo for the electronics of Eris, and a 2600 mAh 4-cell Lipo. The 1600 mAh 2-cell Lipo can be charged using memory slot 2 of the charger. The 2600 mAh 2-cell Lipos can be charged using memory slot 3 for fast charging and memory slot 4 for slower charging (use this if the battery gets run really low for 10-20 minutes then switch to fast charging). The 2600 mAh 4-cell Lipo can be charged using memory slot 8. The 1600 mAh 2-cell and 2600 mAr 4-cell generally charge in 10-20 minutes apiece while I generally fine it takes the 2600 mAh 2-cell up to 70 minutes to charge fully.
=== Setting up the camera system ===
The camera system is run on the windows computer CO3050-07. You can log into this computer using a local microcart username and password which is not posted here for security reasons but any one who works in the lab should know it. Once logged in look for Tracking Tools in the start menu or look for the shortcut shown below:
[[Image:TrackingTools_shortcut.PNG|thumb|center|Tracking Tools shortcut]]
Once the program opens the screen should look something like this:
[[Image:NewTrackingTools.PNG|800px]]
In the Tracking Tools Quick Start pop up menu select Open Existing Project and then navigate to ''D:\Optitrack_Configuration'' (It should open to this directory by default) and select the most recent Tracking Tools project. It should be named like ''TrackingToolsProject YYYY-MM-DD timeStamp.ttp''. This is normally the most recently edited file when sorting by data modified. The most recent one as of August 1st, 2016 is ''TrackingToolsProject 2015-09-23 2.30pm.ttp''.
[[Image:OpeningProject.PNG|800px]]
You should notice that the cameras shown in main project scree arrange themselves like out camera configuration once the project has been opened. Now the constellations need to be loaded. This can be done by going to ''File->Open'' and another pop up window will open. Navigate back to ''D:\Optitrack_Configuration'' (It should open to this directory by default) and select the most recently dated set of RADA trackables. They are named like ''RADA_entireSystem_M_D_YYYY.tra''. The most recent one as of August 1st, 2016 is ''RADA_entireSystem_7_8_2016.tra''.
[[Image:Opening_trackables.PNG|800px]]
Once the project and trackless are open the cameras should appear in their constellation (square) and there should be two constellations under ''Project Explorer->Trackables''. One Named UAV for the pendulum and one named ERIS for the ground vehicle. In order to get additional information about each constellation left click on the the name of the desired trackable.
[[Image:SelectingUAV.PNG|800px]]
Once a trackable is selected more information about it is available in the ''Trackables'' Tab on the right side of the screen. For the current position and orientation look at the ''Real-Time Info'' sub-tab. This gives the orientation in the wrong order for how we currently use the Euler angles. When two or three of the angles are near zero you can switch yaw and pitch to get roughly the correct orientation.
[[Image:Uav_realTimeInfo.PNG|800px]]
Now we need check to make sure the system is zeroed.
1. Hold RADA so that the front of the ground robot (ERIS is facing the wall with the white boards (east)). The front side of Eris is labeled. If it isn't it is the side opposite of the switches and the side with the trackable constellation on it.
2. Make sure that the motor with the red motor mount is also facing the wall with the white boards.
3. Make sure the quad system is aligned along Eris Axis by standing behind the system and seeing if you can use the pole to block mounting bolts of the front propeller motor mount when looking at the pole while facing the east wall.
4. While holding the pendulum approximately vertical see if the camera system reads zeros for the pendulum (UAV) pitch and roll (yaw and roll in ''Real-Time Info''). If yaw is off by a few degrees that is fine.
5. Compare the yaw of the UAV to that of ERIS (Remember this is pitch in ''Real-Time Info''). If they are both near zero and with in a few degrees and the pendulum's pitch/roll were also near zero then you are ready to use the camera system. Otherwise go to the next step.
6. You need to zero the pendulum.
- Align ERIS so it is near zero yaw first (eye ball it).
- Get a level and a friend. Have your friend use a level to ensure that the pendulum is level in both directs and hold it there.
- With the UAV constellation selected go to the ''Orientation'' tab (next to ''Real-Time Info'' tab) and click on ''Reset To Current Orientation button''
- Now your friend can set the pendulum down and you can zero ERIS the same way.
7. Save the new trackable orientation by going to ''File->Save Trakables...'' and save a file using the same naming conventions as the trackable file you opened earlier except use the current data so you don't have to re-zero the system the next time you test.
[[Image:Uav_ResetOrientation.PNG|800px]]
=== Building Software ===
The development environment for running RADA is hosted on CO3050-11, a Linux Red Hat environment. This computer has a local ucart user name that you should use. The password isn't put here for security reasons. In order to ensure that the RADA software is setup correctly for the test you want to run. To do this you will need to open the main.cpp and logger.cpp files and make sure all of the compile time macros you want are defined correctly. All of the c++ files you should need to edit are in the directory ''~/Desktop/rada_research_project/ErisResearchCode/CppProjects/MainProgram_PacketLoss/src/Korebot'' Below is a compiler macro options for main.cpp:
-'''H2ctrl''' : This will cause the system to enter H2 controller mode where the whole RADA system is controlled by an H2 controller.
-'''ssTracking''' : H2ctrl must also be defined for this macro to do anything. This macro will has the system to be controlled by a tracking H2 controller.
-'''ssMotors''' : H2ctrl must also be defined for this macro to do anything. This macro will has the system to be controlled by an H2 contorller that contains propeller states. This also cause the system to "Dance."
-'''ssDrop''' : Cause the system to go into packet drop controller mode. This mode allows controllers designed for lossy networks to be tested. Based off of other definitions how lossy the network is can be simulated. If nothing else is defined this controller becomes basically a H2 controller.
-'''drop10''' : Will put the packet drop mode into 10% loss mode and use a controller designed for 10% loss.
-'''drop30''' : Will put the packet drop mode into 30% loss mode and use a controller designed for 30% loss.
-'''drop50''' : Will put the packet drop mode into 50% loss mode and use a controller designed for 50% loss.
-'''mot50''' : This macro over-rides all other macros. If this is turned on the wheels will not run and the propllers will be run at 50% command. This is used for measuring the effective battery voltage seen by the ESCs. This is always run after a test.
-'''RADAlqi''' : This macro will cause the system to use an LQI controller on the whole system. The linear velocity states are calculated with no filter and the angular velocity states are calculated with filters.
-'''RADAlqi_est''' : This macro will cause the system to use an LQI controller on the whole system. A traditional estimator is used to estimate the states.
-'''rada_lqg''' : This macro will cause the entire system to be controlled by a LQG controller/estimator system.
-'''rada_split_lqg''' : This macro will cause the pendulum and ground robot to be controlled by their own LQG systems.
-'''rada_split_lqg_ol''' : This macro will cause the pendulum to be controlled by an LQG controller, the yaw of the ground robot to be controlled by a PID controller, and the ground robot linear velocities to be controlled with open-loop commands.
-'''yaw_off''' : This macro will cause the yaw control to be disabled on some controllers.
*'''accR''' : This macro will cause the PID linear velocity controllers to be given ramps to acclerate from one velocity to another instead of steps.
-'''posRamp''' : This macro will cause the linear velocities of RADA to be controlled by position PIDs with ramp reference instead of velocity commands.
-If no controller selection is made all controllers revert to PID controllers
All of these macros can be defined simply by uncommenting the corresponding define statement in main.cpp. The macros in the logger.cpp can be seen below:
-'''ssDrop''' : This macro puts the logger into packed drop controller mode and logs the correct values for the packet drop controllers.
-'''RADAlqi''' : This macro puts the logger into full system LQI controller logging mode.
-'''RADAlqi_est''' : This macro puts the logger into full system LQI controller plus estimator logging mode.
-'''rada_lqg''' : This puts the logger into full system LQG controller logging mode.
-'''rada_split_lqg''' : This macro causes the logger to log data about the subsystem LQG controllers.
-'''rada_split_lqg_ol''' : This cause the system to log data about the pendulum LQG system and the open-loop linear velocity commands.
-'''H2ctrl''' : This macro causes the logger to log data about the full system H2 controllers.
-If no logging mode is selected then the logger will default to logging PID data.
Because the system only calculates controllers for one set of controllers it is important to ensure that the logger is in the correct mode based off of what is defined in main.cpp. As of August 1st, 2016 the defines in main.cpp are not seen in logger.cpp.
Finally in a command prompt navigate to the driectroy: ''~/Desktop/rada_research_project/ErisResearchCode/CppProjects/MainProgram_PacketLoss''
Here just type: ''make''. The code will compile for your desired mode. For setting up a new development directory see [http://wikis.ece.iastate.edu/robotic-agriculture-data-acquisition/index.php/Setting_up_a_new_development_environment Setting up a new development environment] from the RADA senior Design wiki.
[[Image:ComplingRADACode.png|800px]]
The complied executable code ends up in ''/home/shared/MainProject''. The ''/home/shared'' directory is setup as a network file share (NFS).
[[Image:ErisCompliedCode-config.png|800px]]
This service needs to be restarted when CO3050-11 is restarted. [http://wikis.ece.iastate.edu/robotic-agriculture-data-acquisition/index.php/Configuring_NFS_shares_for_the_robot Configure NFS shares for the robot] from the RADA Senior Design wiki. Be sure to use the new Linux install command in step six. Though I have fond that even on a good strt the ''[ok]'' messages will still print.
=== Turing on RADA ===
Turing on Eris is fairly simple. Each system has its own battery. There is one for the wheels that plugs in at the front of Eris (opposite side of the swiches), one for the electronics in the back of Eris (in between the switches), and one for the propellers that goes on top of Eris.
[[Image:ErisOnPhoto.jpg|800px]]
The wheel battery is normally 1600 mAh 2-cell Lipo but any 2-cell Lipo will work. The wheels are turned on by flipping the silver switch so the top points away from the system. The electronics normally use a 2600 mAh 2-cell Lipo. The electronics are turned on by flipping the green switch away from the system. It is important that you only the WIFI adapter or Ethernet plugged in at the same time or VRPN my listen to the camera data broadcast over both connects which could cause problems. The propeller system is powered via a 2600 mAh 4-cell Lipo that connects to a power cable at the base of the pendulum. There is a switch to turn on the power to the propellers system. You will know it is on when the 1 on the switch is flush with the switch housing instead of sticking out. It takes about 30 seconds to a minute for Eris to boot up and start the networking connections. When the WIFI is plugged in you will know it is ready when a blue light turns on, on the module.
=== Connecting to RADA ===
RADA is controlled through an SSH connection. in a commands prompt, not the one you compile the code from so that you can recompile for different setup with out needing to close the connection. If you are using a WIFI connect use the command ''ssh root@192.168.0.53''. If you are connected to Eris through a LAN connaction use the command ''ssh root@192.168.0.54''. If the connection goes though you should be proped for a password.
The password is ''rootme''.
[[Image:Ssh2Eris.png|800px]]
It is important to close the SSH connection before turning off Eris because the terminal you are using will hang up if you don't. You can close the connection by using the command ''exit''.
[[Image:ClosingSSH.png|800px]]
== Testing RADA ==
=== Running the first test after power up ===
=== Running additional tests ===
=== Locating and retrieving log files ===
=== Measuring battery voltages ===
== Post processing and Simulation ==
=== Using the MATLAB data parsing tool ===
=== Adding additional data for simulations ===
=== Setting up the MATLAB workspace for simulation ===
=== Running simulations and storing results ===
=== Plotting results ===
2ab5c9a9a57014fddc31c492cf78f5119d6f4b21
230
225
2016-08-02T17:32:40Z
Pfuhing
5
/* Testing RADA */
wikitext
text/x-wiki
This page will take you though setting up and testing RADA, retrieving the log file and other necessary data to run a simulation of that test and processing the data in MATLAB. Then actually running the simulation of RADA in Simulink.
== Setting Up a RADA Test ==
Testing RADA is not overly difficult once you get the hang of the steps to setup RADA. The following steps may seem like a long process to go from starting the testing process to having completed simulation and plotting of the test results but this whole test procedure (with the exception of battery charging) can be completed in about 15-20 minutes. These steps are meant to be as detailed as possible in order to help new users of RADA to get up and running as quickly as possible.
'''<span style="color:red">NOTE: Always run RADA with at least 2 people!</span>''' The pendulum arm can crash into the ground if the network starts to drop packets and one person cannot give commands to RADA and spot the pendulum. This is a safety issue for both you and the RADA platform.
=== Charging batteries ===
The lab currently uses mostly Hyperion batteries. We charge our batteries with a Hyperion EOS 1420i Net3 battery charger. For some general information about how to use this charger see [https://www.youtube.com/watch?v=-ox3EpzvsJ8 this video.]. In the lab we power this charger using the old Kepco Power supplu because it is the only power supply that we have that can supply enough current. Make sure that the power supply is set to an output voltage between 10.5V-29V.
{| class="wikitable" style="text-align:center"
|-
| [[Image:ChargerPowerSupplyOff.JPG|400px]]
| [[Image:ChargerPowerSuplyOn.JPG|400px]]
|-
| Kepco Power Supply off.
| Kepco Power Supply on with correct voltage supply range.
|}
While the YouTube video linked above should explain how to use the charger. Currently three different Lithium polymer batteries (Lipo): 1600 mAh 2-cell Lipo for the wheels, 2600 mAh 2-cell Lipo for the electronics of Eris, and a 2600 mAh 4-cell Lipo. The 1600 mAh 2-cell Lipo can be charged using memory slot 2 of the charger. The 2600 mAh 2-cell Lipos can be charged using memory slot 3 for fast charging and memory slot 4 for slower charging (use this if the battery gets run really low for 10-20 minutes then switch to fast charging). The 2600 mAh 4-cell Lipo can be charged using memory slot 8. The 1600 mAh 2-cell and 2600 mAr 4-cell generally charge in 10-20 minutes apiece while I generally fine it takes the 2600 mAh 2-cell up to 70 minutes to charge fully.
=== Setting up the camera system ===
The camera system is run on the windows computer CO3050-07. You can log into this computer using a local microcart username and password which is not posted here for security reasons but any one who works in the lab should know it. Once logged in look for Tracking Tools in the start menu or look for the shortcut shown below:
[[Image:TrackingTools_shortcut.PNG|thumb|center|Tracking Tools shortcut]]
Once the program opens the screen should look something like this:
[[Image:NewTrackingTools.PNG|800px]]
In the Tracking Tools Quick Start pop up menu select Open Existing Project and then navigate to ''D:\Optitrack_Configuration'' (It should open to this directory by default) and select the most recent Tracking Tools project. It should be named like ''TrackingToolsProject YYYY-MM-DD timeStamp.ttp''. This is normally the most recently edited file when sorting by data modified. The most recent one as of August 1st, 2016 is ''TrackingToolsProject 2015-09-23 2.30pm.ttp''.
[[Image:OpeningProject.PNG|800px]]
You should notice that the cameras shown in main project scree arrange themselves like out camera configuration once the project has been opened. Now the constellations need to be loaded. This can be done by going to ''File->Open'' and another pop up window will open. Navigate back to ''D:\Optitrack_Configuration'' (It should open to this directory by default) and select the most recently dated set of RADA trackables. They are named like ''RADA_entireSystem_M_D_YYYY.tra''. The most recent one as of August 1st, 2016 is ''RADA_entireSystem_7_8_2016.tra''.
[[Image:Opening_trackables.PNG|800px]]
Once the project and trackless are open the cameras should appear in their constellation (square) and there should be two constellations under ''Project Explorer->Trackables''. One Named UAV for the pendulum and one named ERIS for the ground vehicle. In order to get additional information about each constellation left click on the the name of the desired trackable.
[[Image:SelectingUAV.PNG|800px]]
Once a trackable is selected more information about it is available in the ''Trackables'' Tab on the right side of the screen. For the current position and orientation look at the ''Real-Time Info'' sub-tab. This gives the orientation in the wrong order for how we currently use the Euler angles. When two or three of the angles are near zero you can switch yaw and pitch to get roughly the correct orientation.
[[Image:Uav_realTimeInfo.PNG|800px]]
Now we need check to make sure the system is zeroed.
1. Hold RADA so that the front of the ground robot (ERIS is facing the wall with the white boards (east)). The front side of Eris is labeled. If it isn't it is the side opposite of the switches and the side with the trackable constellation on it.
2. Make sure that the motor with the red motor mount is also facing the wall with the white boards.
3. Make sure the quad system is aligned along Eris Axis by standing behind the system and seeing if you can use the pole to block mounting bolts of the front propeller motor mount when looking at the pole while facing the east wall.
4. While holding the pendulum approximately vertical see if the camera system reads zeros for the pendulum (UAV) pitch and roll (yaw and roll in ''Real-Time Info''). If yaw is off by a few degrees that is fine.
5. Compare the yaw of the UAV to that of ERIS (Remember this is pitch in ''Real-Time Info''). If they are both near zero and with in a few degrees and the pendulum's pitch/roll were also near zero then you are ready to use the camera system. Otherwise go to the next step.
6. You need to zero the pendulum.
- Align ERIS so it is near zero yaw first (eye ball it).
- Get a level and a friend. Have your friend use a level to ensure that the pendulum is level in both directs and hold it there.
- With the UAV constellation selected go to the ''Orientation'' tab (next to ''Real-Time Info'' tab) and click on ''Reset To Current Orientation button''
- Now your friend can set the pendulum down and you can zero ERIS the same way.
7. Save the new trackable orientation by going to ''File->Save Trakables...'' and save a file using the same naming conventions as the trackable file you opened earlier except use the current data so you don't have to re-zero the system the next time you test.
[[Image:Uav_ResetOrientation.PNG|800px]]
=== Building Software ===
The development environment for running RADA is hosted on CO3050-11, a Linux Red Hat environment. This computer has a local ucart user name that you should use. The password isn't put here for security reasons. In order to ensure that the RADA software is setup correctly for the test you want to run. To do this you will need to open the main.cpp and logger.cpp files and make sure all of the compile time macros you want are defined correctly. All of the c++ files you should need to edit are in the directory ''~/Desktop/rada_research_project/ErisResearchCode/CppProjects/MainProgram_PacketLoss/src/Korebot'' Below is a compiler macro options for main.cpp:
-'''H2ctrl''' : This will cause the system to enter H2 controller mode where the whole RADA system is controlled by an H2 controller.
-'''ssTracking''' : H2ctrl must also be defined for this macro to do anything. This macro will has the system to be controlled by a tracking H2 controller.
-'''ssMotors''' : H2ctrl must also be defined for this macro to do anything. This macro will has the system to be controlled by an H2 contorller that contains propeller states. This also cause the system to "Dance."
-'''ssDrop''' : Cause the system to go into packet drop controller mode. This mode allows controllers designed for lossy networks to be tested. Based off of other definitions how lossy the network is can be simulated. If nothing else is defined this controller becomes basically a H2 controller.
-'''drop10''' : Will put the packet drop mode into 10% loss mode and use a controller designed for 10% loss.
-'''drop30''' : Will put the packet drop mode into 30% loss mode and use a controller designed for 30% loss.
-'''drop50''' : Will put the packet drop mode into 50% loss mode and use a controller designed for 50% loss.
-'''mot50''' : This macro over-rides all other macros. If this is turned on the wheels will not run and the propllers will be run at 50% command. This is used for measuring the effective battery voltage seen by the ESCs. This is always run after a test.
-'''RADAlqi''' : This macro will cause the system to use an LQI controller on the whole system. The linear velocity states are calculated with no filter and the angular velocity states are calculated with filters.
-'''RADAlqi_est''' : This macro will cause the system to use an LQI controller on the whole system. A traditional estimator is used to estimate the states.
-'''rada_lqg''' : This macro will cause the entire system to be controlled by a LQG controller/estimator system.
-'''rada_split_lqg''' : This macro will cause the pendulum and ground robot to be controlled by their own LQG systems.
-'''rada_split_lqg_ol''' : This macro will cause the pendulum to be controlled by an LQG controller, the yaw of the ground robot to be controlled by a PID controller, and the ground robot linear velocities to be controlled with open-loop commands.
-'''yaw_off''' : This macro will cause the yaw control to be disabled on some controllers.
*'''accR''' : This macro will cause the PID linear velocity controllers to be given ramps to acclerate from one velocity to another instead of steps.
-'''posRamp''' : This macro will cause the linear velocities of RADA to be controlled by position PIDs with ramp reference instead of velocity commands.
-If no controller selection is made all controllers revert to PID controllers
All of these macros can be defined simply by uncommenting the corresponding define statement in main.cpp. The macros in the logger.cpp can be seen below:
-'''ssDrop''' : This macro puts the logger into packed drop controller mode and logs the correct values for the packet drop controllers.
-'''RADAlqi''' : This macro puts the logger into full system LQI controller logging mode.
-'''RADAlqi_est''' : This macro puts the logger into full system LQI controller plus estimator logging mode.
-'''rada_lqg''' : This puts the logger into full system LQG controller logging mode.
-'''rada_split_lqg''' : This macro causes the logger to log data about the subsystem LQG controllers.
-'''rada_split_lqg_ol''' : This cause the system to log data about the pendulum LQG system and the open-loop linear velocity commands.
-'''H2ctrl''' : This macro causes the logger to log data about the full system H2 controllers.
-If no logging mode is selected then the logger will default to logging PID data.
Because the system only calculates controllers for one set of controllers it is important to ensure that the logger is in the correct mode based off of what is defined in main.cpp. As of August 1st, 2016 the defines in main.cpp are not seen in logger.cpp.
Finally in a command prompt navigate to the driectroy: ''~/Desktop/rada_research_project/ErisResearchCode/CppProjects/MainProgram_PacketLoss''
Here just type: ''make''. The code will compile for your desired mode. For setting up a new development directory see [http://wikis.ece.iastate.edu/robotic-agriculture-data-acquisition/index.php/Setting_up_a_new_development_environment Setting up a new development environment] from the RADA senior Design wiki.
[[Image:ComplingRADACode.png|800px]]
The complied executable code ends up in ''/home/shared/MainProject''. The ''/home/shared'' directory is setup as a network file share (NFS).
[[Image:ErisCompliedCode-config.png|800px]]
This service needs to be restarted when CO3050-11 is restarted. [http://wikis.ece.iastate.edu/robotic-agriculture-data-acquisition/index.php/Configuring_NFS_shares_for_the_robot Configure NFS shares for the robot] from the RADA Senior Design wiki. Be sure to use the new Linux install command in step six. Though I have fond that even on a good strt the ''[ok]'' messages will still print.
=== Turing on RADA ===
Turing on Eris is fairly simple. Each system has its own battery. There is one for the wheels that plugs in at the front of Eris (opposite side of the swiches), one for the electronics in the back of Eris (in between the switches), and one for the propellers that goes on top of Eris.
[[Image:ErisOnPhoto.jpg|800px]]
The wheel battery is normally 1600 mAh 2-cell Lipo but any 2-cell Lipo will work. The wheels are turned on by flipping the silver switch so the top points away from the system. The electronics normally use a 2600 mAh 2-cell Lipo. The electronics are turned on by flipping the green switch away from the system. It is important that you only the WIFI adapter or Ethernet plugged in at the same time or VRPN my listen to the camera data broadcast over both connects which could cause problems. The propeller system is powered via a 2600 mAh 4-cell Lipo that connects to a power cable at the base of the pendulum. There is a switch to turn on the power to the propellers system. You will know it is on when the 1 on the switch is flush with the switch housing instead of sticking out. It takes about 30 seconds to a minute for Eris to boot up and start the networking connections. When the WIFI is plugged in you will know it is ready when a blue light turns on, on the module.
=== Connecting to RADA ===
RADA is controlled through an SSH connection. in a commands prompt, not the one you compile the code from so that you can recompile for different setup with out needing to close the connection. If you are using a WIFI connect use the command ''ssh root@192.168.0.53''. If you are connected to Eris through a LAN connaction use the command ''ssh root@192.168.0.54''. If the connection goes though you should be proped for a password.
The password is ''rootme''.
[[Image:Ssh2Eris.png|800px]]
It is important to close the SSH connection before turning off Eris because the terminal you are using will hang up if you don't. You can close the connection by using the command ''exit''.
[[Image:ClosingSSH.png|800px]]
== Testing RADA ==
Now that you are connected to Eris you can run tests. The testing is started by a few different methods.
=== Running the first test after power up ===
For the firs test after powering on Eris a few additional steps need to be completed in order to test the system. The FPGA motor controller needs to be programmed and Eris needs to connect the the NFS server running on CO3050-11. This is accomplished by running ''1_co3050-11.sh'', this shell scrip will setup the NFS, load the bit file into the FPGA configuration memory. Then it retrieves the executable file from the NFS server ''/mnt/nfs/MainProject and runs the executable. Once the user exits the executable the log file produces is copied from the ''~/Logs/YYYY_MM_DD_Day'' directory on Eris to ''/home/shared/MainProject/Logs/YYYY_MM_DD_Day'' on CO3050-11. When the folder for the current Eris date doesn't exist it creates this directory in CO3050-11 and then removes the directory and log file from Eris. You may see an warning that when coping the log file Eris couldn't maintain the file permisiion settings. This is normal as Eris doesn't have the same access to the NSF server as it has to its own files. This Date stamp uses date on Eris which is currently in June of 2008 as of August 2nd, 2016.
Before starting the test it is best to have someone spotting the pendulum a holding it near vertical so that the pendulum doesn't have issues when entering a control mode. This shell scrip is run by using the command ''./1_co3050-11.sh'' in the terminal with the open SSH connection to Eris from the home, ''/root'', directory of Eris. When you run this script there will be a bunch of information printed out about the PIC bus and loading the bit file to configure the FPGA, you will know that RADA is ready for the test when it asks you to select a running mode. See the Testing Modes section below. This script can take a while to complete so beyond the first test after start up you don't need to run this script. See the Section about Running additional tests below.
=== Testing Modes ===
==== Robot Control Model ====
==== Tuning Mode ====
==== Box Step Mode ====
=== Running additional Tests ===
=== Locating and retrieving log files ===
=== Measuring battery voltages ===
==== Wheel Battery ====
==== Quad Battery ====
== Post processing and Simulation ==
=== Using the MATLAB data parsing tool ===
=== Adding additional data for simulations ===
=== Setting up the MATLAB workspace for simulation ===
=== Running simulations and storing results ===
=== Plotting results ===
f6a85f9ce611f12015cc18b057d2a357deacc98a
231
230
2016-08-02T18:20:22Z
Pfuhing
5
/* Testing RADA */
wikitext
text/x-wiki
This page will take you though setting up and testing RADA, retrieving the log file and other necessary data to run a simulation of that test and processing the data in MATLAB. Then actually running the simulation of RADA in Simulink.
== Setting Up a RADA Test ==
Testing RADA is not overly difficult once you get the hang of the steps to setup RADA. The following steps may seem like a long process to go from starting the testing process to having completed simulation and plotting of the test results but this whole test procedure (with the exception of battery charging) can be completed in about 15-20 minutes. These steps are meant to be as detailed as possible in order to help new users of RADA to get up and running as quickly as possible.
'''<span style="color:red">NOTE: Always run RADA with at least 2 people!</span>''' The pendulum arm can crash into the ground if the network starts to drop packets and one person cannot give commands to RADA and spot the pendulum. This is a safety issue for both you and the RADA platform.
=== Charging batteries ===
The lab currently uses mostly Hyperion batteries. We charge our batteries with a Hyperion EOS 1420i Net3 battery charger. For some general information about how to use this charger see [https://www.youtube.com/watch?v=-ox3EpzvsJ8 this video.]. In the lab we power this charger using the old Kepco Power supplu because it is the only power supply that we have that can supply enough current. Make sure that the power supply is set to an output voltage between 10.5V-29V.
{| class="wikitable" style="text-align:center"
|-
| [[Image:ChargerPowerSupplyOff.JPG|400px]]
| [[Image:ChargerPowerSuplyOn.JPG|400px]]
|-
| Kepco Power Supply off.
| Kepco Power Supply on with correct voltage supply range.
|}
While the YouTube video linked above should explain how to use the charger. Currently three different Lithium polymer batteries (Lipo): 1600 mAh 2-cell Lipo for the wheels, 2600 mAh 2-cell Lipo for the electronics of Eris, and a 2600 mAh 4-cell Lipo. The 1600 mAh 2-cell Lipo can be charged using memory slot 2 of the charger. The 2600 mAh 2-cell Lipos can be charged using memory slot 3 for fast charging and memory slot 4 for slower charging (use this if the battery gets run really low for 10-20 minutes then switch to fast charging). The 2600 mAh 4-cell Lipo can be charged using memory slot 8. The 1600 mAh 2-cell and 2600 mAr 4-cell generally charge in 10-20 minutes apiece while I generally fine it takes the 2600 mAh 2-cell up to 70 minutes to charge fully.
=== Setting up the camera system ===
The camera system is run on the windows computer CO3050-07. You can log into this computer using a local microcart username and password which is not posted here for security reasons but any one who works in the lab should know it. Once logged in look for Tracking Tools in the start menu or look for the shortcut shown below:
[[Image:TrackingTools_shortcut.PNG|thumb|center|Tracking Tools shortcut]]
Once the program opens the screen should look something like this:
[[Image:NewTrackingTools.PNG|800px]]
In the Tracking Tools Quick Start pop up menu select Open Existing Project and then navigate to ''D:\Optitrack_Configuration'' (It should open to this directory by default) and select the most recent Tracking Tools project. It should be named like ''TrackingToolsProject YYYY-MM-DD timeStamp.ttp''. This is normally the most recently edited file when sorting by data modified. The most recent one as of August 1st, 2016 is ''TrackingToolsProject 2015-09-23 2.30pm.ttp''.
[[Image:OpeningProject.PNG|800px]]
You should notice that the cameras shown in main project scree arrange themselves like out camera configuration once the project has been opened. Now the constellations need to be loaded. This can be done by going to ''File->Open'' and another pop up window will open. Navigate back to ''D:\Optitrack_Configuration'' (It should open to this directory by default) and select the most recently dated set of RADA trackables. They are named like ''RADA_entireSystem_M_D_YYYY.tra''. The most recent one as of August 1st, 2016 is ''RADA_entireSystem_7_8_2016.tra''.
[[Image:Opening_trackables.PNG|800px]]
Once the project and trackless are open the cameras should appear in their constellation (square) and there should be two constellations under ''Project Explorer->Trackables''. One Named UAV for the pendulum and one named ERIS for the ground vehicle. In order to get additional information about each constellation left click on the the name of the desired trackable.
[[Image:SelectingUAV.PNG|800px]]
Once a trackable is selected more information about it is available in the ''Trackables'' Tab on the right side of the screen. For the current position and orientation look at the ''Real-Time Info'' sub-tab. This gives the orientation in the wrong order for how we currently use the Euler angles. When two or three of the angles are near zero you can switch yaw and pitch to get roughly the correct orientation.
[[Image:Uav_realTimeInfo.PNG|800px]]
Now we need check to make sure the system is zeroed.
1. Hold RADA so that the front of the ground robot (ERIS is facing the wall with the white boards (east)). The front side of Eris is labeled. If it isn't it is the side opposite of the switches and the side with the trackable constellation on it.
2. Make sure that the motor with the red motor mount is also facing the wall with the white boards.
3. Make sure the quad system is aligned along Eris Axis by standing behind the system and seeing if you can use the pole to block mounting bolts of the front propeller motor mount when looking at the pole while facing the east wall.
4. While holding the pendulum approximately vertical see if the camera system reads zeros for the pendulum (UAV) pitch and roll (yaw and roll in ''Real-Time Info''). If yaw is off by a few degrees that is fine.
5. Compare the yaw of the UAV to that of ERIS (Remember this is pitch in ''Real-Time Info''). If they are both near zero and with in a few degrees and the pendulum's pitch/roll were also near zero then you are ready to use the camera system. Otherwise go to the next step.
6. You need to zero the pendulum.
- Align ERIS so it is near zero yaw first (eye ball it).
- Get a level and a friend. Have your friend use a level to ensure that the pendulum is level in both directs and hold it there.
- With the UAV constellation selected go to the ''Orientation'' tab (next to ''Real-Time Info'' tab) and click on ''Reset To Current Orientation button''
- Now your friend can set the pendulum down and you can zero ERIS the same way.
7. Save the new trackable orientation by going to ''File->Save Trakables...'' and save a file using the same naming conventions as the trackable file you opened earlier except use the current data so you don't have to re-zero the system the next time you test.
[[Image:Uav_ResetOrientation.PNG|800px]]
=== Building Software ===
The development environment for running RADA is hosted on CO3050-11, a Linux Red Hat environment. This computer has a local ucart user name that you should use. The password isn't put here for security reasons. In order to ensure that the RADA software is setup correctly for the test you want to run. To do this you will need to open the main.cpp and logger.cpp files and make sure all of the compile time macros you want are defined correctly. All of the c++ files you should need to edit are in the directory ''~/Desktop/rada_research_project/ErisResearchCode/CppProjects/MainProgram_PacketLoss/src/Korebot'' Below is a compiler macro options for main.cpp:
-'''H2ctrl''' : This will cause the system to enter H2 controller mode where the whole RADA system is controlled by an H2 controller.
-'''ssTracking''' : H2ctrl must also be defined for this macro to do anything. This macro will has the system to be controlled by a tracking H2 controller.
-'''ssMotors''' : H2ctrl must also be defined for this macro to do anything. This macro will has the system to be controlled by an H2 contorller that contains propeller states. This also cause the system to "Dance."
-'''ssDrop''' : Cause the system to go into packet drop controller mode. This mode allows controllers designed for lossy networks to be tested. Based off of other definitions how lossy the network is can be simulated. If nothing else is defined this controller becomes basically a H2 controller.
-'''drop10''' : Will put the packet drop mode into 10% loss mode and use a controller designed for 10% loss.
-'''drop30''' : Will put the packet drop mode into 30% loss mode and use a controller designed for 30% loss.
-'''drop50''' : Will put the packet drop mode into 50% loss mode and use a controller designed for 50% loss.
-'''mot50''' : This macro over-rides all other macros. If this is turned on the wheels will not run and the propllers will be run at 50% command. This is used for measuring the effective battery voltage seen by the ESCs. This is always run after a test.
-'''RADAlqi''' : This macro will cause the system to use an LQI controller on the whole system. The linear velocity states are calculated with no filter and the angular velocity states are calculated with filters.
-'''RADAlqi_est''' : This macro will cause the system to use an LQI controller on the whole system. A traditional estimator is used to estimate the states.
-'''rada_lqg''' : This macro will cause the entire system to be controlled by a LQG controller/estimator system.
-'''rada_split_lqg''' : This macro will cause the pendulum and ground robot to be controlled by their own LQG systems.
-'''rada_split_lqg_ol''' : This macro will cause the pendulum to be controlled by an LQG controller, the yaw of the ground robot to be controlled by a PID controller, and the ground robot linear velocities to be controlled with open-loop commands.
-'''yaw_off''' : This macro will cause the yaw control to be disabled on some controllers.
*'''accR''' : This macro will cause the PID linear velocity controllers to be given ramps to acclerate from one velocity to another instead of steps.
-'''posRamp''' : This macro will cause the linear velocities of RADA to be controlled by position PIDs with ramp reference instead of velocity commands.
-If no controller selection is made all controllers revert to PID controllers
All of these macros can be defined simply by uncommenting the corresponding define statement in main.cpp. The macros in the logger.cpp can be seen below:
-'''ssDrop''' : This macro puts the logger into packed drop controller mode and logs the correct values for the packet drop controllers.
-'''RADAlqi''' : This macro puts the logger into full system LQI controller logging mode.
-'''RADAlqi_est''' : This macro puts the logger into full system LQI controller plus estimator logging mode.
-'''rada_lqg''' : This puts the logger into full system LQG controller logging mode.
-'''rada_split_lqg''' : This macro causes the logger to log data about the subsystem LQG controllers.
-'''rada_split_lqg_ol''' : This cause the system to log data about the pendulum LQG system and the open-loop linear velocity commands.
-'''H2ctrl''' : This macro causes the logger to log data about the full system H2 controllers.
-If no logging mode is selected then the logger will default to logging PID data.
Because the system only calculates controllers for one set of controllers it is important to ensure that the logger is in the correct mode based off of what is defined in main.cpp. As of August 1st, 2016 the defines in main.cpp are not seen in logger.cpp.
Finally in a command prompt navigate to the driectroy: ''~/Desktop/rada_research_project/ErisResearchCode/CppProjects/MainProgram_PacketLoss''
Here just type: ''make''. The code will compile for your desired mode. For setting up a new development directory see [http://wikis.ece.iastate.edu/robotic-agriculture-data-acquisition/index.php/Setting_up_a_new_development_environment Setting up a new development environment] from the RADA senior Design wiki.
[[Image:ComplingRADACode.png|800px]]
The complied executable code ends up in ''/home/shared/MainProject''. The ''/home/shared'' directory is setup as a network file share (NFS).
[[Image:ErisCompliedCode-config.png|800px]]
This service needs to be restarted when CO3050-11 is restarted. [http://wikis.ece.iastate.edu/robotic-agriculture-data-acquisition/index.php/Configuring_NFS_shares_for_the_robot Configure NFS shares for the robot] from the RADA Senior Design wiki. Be sure to use the new Linux install command in step six. Though I have fond that even on a good strt the ''[ok]'' messages will still print.
=== Turing on RADA ===
Turing on Eris is fairly simple. Each system has its own battery. There is one for the wheels that plugs in at the front of Eris (opposite side of the swiches), one for the electronics in the back of Eris (in between the switches), and one for the propellers that goes on top of Eris.
[[Image:ErisOnPhoto.jpg|800px]]
The wheel battery is normally 1600 mAh 2-cell Lipo but any 2-cell Lipo will work. The wheels are turned on by flipping the silver switch so the top points away from the system. The electronics normally use a 2600 mAh 2-cell Lipo. The electronics are turned on by flipping the green switch away from the system. It is important that you only the WIFI adapter or Ethernet plugged in at the same time or VRPN my listen to the camera data broadcast over both connects which could cause problems. The propeller system is powered via a 2600 mAh 4-cell Lipo that connects to a power cable at the base of the pendulum. There is a switch to turn on the power to the propellers system. You will know it is on when the 1 on the switch is flush with the switch housing instead of sticking out. It takes about 30 seconds to a minute for Eris to boot up and start the networking connections. When the WIFI is plugged in you will know it is ready when a blue light turns on, on the module.
=== Connecting to RADA ===
RADA is controlled through an SSH connection. in a commands prompt, not the one you compile the code from so that you can recompile for different setup with out needing to close the connection. If you are using a WIFI connect use the command ''ssh root@192.168.0.53''. If you are connected to Eris through a LAN connaction use the command ''ssh root@192.168.0.54''. If the connection goes though you should be proped for a password.
The password is ''rootme''.
[[Image:Ssh2Eris.png|800px]]
It is important to close the SSH connection before turning off Eris because the terminal you are using will hang up if you don't. You can close the connection by using the command ''exit''.
[[Image:ClosingSSH.png|800px]]
== Testing RADA ==
Now that you are connected to Eris you can run tests. The testing is started by a few different methods.
=== Running the first test after power up ===
For the firs test after powering on Eris a few additional steps need to be completed in order to test the system. The FPGA motor controller needs to be programmed and Eris needs to connect the the NFS server running on CO3050-11. This is accomplished by running ''1_co3050-11.sh'', this shell scrip will setup the NFS, load the bit file into the FPGA configuration memory. Then it retrieves the executable file from the NFS server ''/mnt/nfs/MainProject and runs the executable. Once the user exits the executable the log file produces is copied from the ''~/Logs/YYYY_MM_DD_Day'' directory on Eris to ''/home/shared/MainProject/Logs/YYYY_MM_DD_Day'' on CO3050-11. When the folder for the current Eris date doesn't exist it creates this directory in CO3050-11 and then removes the directory and log file from Eris. You may see an warning that when coping the log file Eris couldn't maintain the file permisiion settings. This is normal as Eris doesn't have the same access to the NSF server as it has to its own files. This Date stamp uses date on Eris which is currently in June of 2008 as of August 2nd, 2016.
Before starting the test it is best to have someone spotting the pendulum a holding it near vertical so that the pendulum doesn't have issues when entering a control mode.'''<span style="color:red"> Always run ensure the pendulum is spotted by a second person when testing so you don't hurt yourself, others in the lab, or the RADA system.</span>''' Once you spotter is ready run the shell scrip by= using the command ''./1_co3050-11.sh'' in the terminal with the open SSH connection to Eris from the home, ''/root'', directory of Eris. When you run this script there will be a bunch of information printed out about the PIC bus and loading the bit file to configure the FPGA, you will know that RADA is ready for the test when it asks you to select a running mode. See the Testing Modes section below. This script can take a while to complete so beyond the first test after start up you don't need to run this script. See the Section about Running additional tests below.
[[Image:StartingRADA initial.png|800px]]
=== Testing Modes ===
The RADA system has three testing modes: Robot Control Mode, Tuning Mode, and Box Step Mode. Additionally you can exit the execution at any time by pressing the ''Esc'' key. Once the terminal asks you to chose a mode you can use the following commands to enter the desired mode with a three second delay or exit the program. You can also use these commands to switch between the modes.
-''v'' : Enters the pendulum PID tuning mode, this will only really work when using PIDs to control the pendulum.
-''b'' : Enter Robot control mode, in this mode you can drive the robot around and the pendulum will try to stay vertical. This is the main mode used for testing the whole RADA system.
-''n'' : Enters box step mode, where the pendulum will change its desired pitch and roll angles every 20 seconds and move in a box shape.
-''Esc'' : By hitting the escape key the program will exit the program.
You will almost always want to run Robot Control Mode as the other modes are legacy modes from when we initially built and tested RADA and only works with the pendulum PID controllers. There are also a few utility commands that can be used in all modes.
-''2'' : Resets I composts of the Pitch/Roll PIDs and only the PIDs.
-''m'' : Adds a marker to the Log file incase odd things happen somewhere. This just increments a counter so if you use it look for changes in the marker value.
==== Robot Control Model ====
In Robot control mode you can control the motion of Eris. For PID control of Eris or 1D state feedback system the directional commands command Eris body velocity were for full system and Eris system state feedback controllers control the global velocity. All of these keys only need to be pressed not held down.
-''w'' : Moves Eris forward (+x) at some velocity depending on the controller.
-''s'' : Moves Eris in reverse (-x) at some velocity depending on the controller.
-''d'' : Moves Eris in right (+y) at some velocity depending on the controller.
-''a'' : Moves Eris in left (-y) at some velocity depending on the controller.
-''p'' : Stops the motion of Eris (Set all velocity set points to zero). I.e. if you hit ''w'' then hit ''s'' then Eris will be moving in reverse.
-''y'' : Moves Eris forward and to the right (+x/+y) simultaneously at some velocity depending on the controller.
-''t'' : Moves Eris forward and to the left (+x/-y) simultaneously at some velocity depending on the controller.
-''i'' : Moves Eris reverse and to the right (-x/+y) simultaneously at some velocity depending on the controller.
-''y'' : Moves Eris reverse and to the left (-x/-y) simultaneously at some velocity depending on the controller.
-''e'' : Rotate Eris clockwise (+yaw) at some angular rate. This only worked when RADA used the closed-loop FPGA control of the wheels. There is currently no controllers that use this command.
-''q'' : Rotate Eris counter-clockwise (-yaw) at some angular rate. This only worked when RADA used the closed-loop FPGA control of the wheels. There is currently no controllers that use this command.
-''<'' : Increment Eris' desired heading 45 degrees counter-clockwise (-yaw).
-''>'' : Increment Eris' desired heading 45 degrees clockwise (+yaw).
-''7'' : Increments the pitch set point (+pitch).
-''4'' : Decrements the pitch set point (-pitch).
-''8'' : Increments the roll set point (+roll).
-''5'' : Decrements the roll set point (-roll).
==== Tuning Mode ====
Tuning mode allows you to tune the PID controllers for both pitch and roll. The UI commands here are also available in Box Step Mode.
==== Box Step Mode ====
=== Running additional Tests ===
=== Locating and retrieving log files ===
=== Measuring battery voltages ===
==== Wheel Battery ====
==== Quad Battery ====
== Post processing and Simulation ==
=== Using the MATLAB data parsing tool ===
=== Adding additional data for simulations ===
=== Setting up the MATLAB workspace for simulation ===
=== Running simulations and storing results ===
=== Plotting results ===
6bd19381a57788ca07631cf9b062a6ebce7be93f
239
231
2016-08-02T19:35:31Z
Pfuhing
5
/* Testing RADA */
wikitext
text/x-wiki
This page will take you though setting up and testing RADA, retrieving the log file and other necessary data to run a simulation of that test and processing the data in MATLAB. Then actually running the simulation of RADA in Simulink.
== Setting Up a RADA Test ==
Testing RADA is not overly difficult once you get the hang of the steps to setup RADA. The following steps may seem like a long process to go from starting the testing process to having completed simulation and plotting of the test results but this whole test procedure (with the exception of battery charging) can be completed in about 15-20 minutes. These steps are meant to be as detailed as possible in order to help new users of RADA to get up and running as quickly as possible.
'''<span style="color:red">NOTE: Always run RADA with at least 2 people!</span>''' The pendulum arm can crash into the ground if the network starts to drop packets and one person cannot give commands to RADA and spot the pendulum. This is a safety issue for both you and the RADA platform.
=== Charging batteries ===
The lab currently uses mostly Hyperion batteries. We charge our batteries with a Hyperion EOS 1420i Net3 battery charger. For some general information about how to use this charger see [https://www.youtube.com/watch?v=-ox3EpzvsJ8 this video.]. In the lab we power this charger using the old Kepco Power supplu because it is the only power supply that we have that can supply enough current. Make sure that the power supply is set to an output voltage between 10.5V-29V.
{| class="wikitable" style="text-align:center"
|-
| [[Image:ChargerPowerSupplyOff.JPG|400px]]
| [[Image:ChargerPowerSuplyOn.JPG|400px]]
|-
| Kepco Power Supply off.
| Kepco Power Supply on with correct voltage supply range.
|}
While the YouTube video linked above should explain how to use the charger. Currently three different Lithium polymer batteries (Lipo): 1600 mAh 2-cell Lipo for the wheels, 2600 mAh 2-cell Lipo for the electronics of Eris, and a 2600 mAh 4-cell Lipo. The 1600 mAh 2-cell Lipo can be charged using memory slot 2 of the charger. The 2600 mAh 2-cell Lipos can be charged using memory slot 3 for fast charging and memory slot 4 for slower charging (use this if the battery gets run really low for 10-20 minutes then switch to fast charging). The 2600 mAh 4-cell Lipo can be charged using memory slot 8. The 1600 mAh 2-cell and 2600 mAr 4-cell generally charge in 10-20 minutes apiece while I generally fine it takes the 2600 mAh 2-cell up to 70 minutes to charge fully.
=== Setting up the camera system ===
The camera system is run on the windows computer CO3050-07. You can log into this computer using a local microcart username and password which is not posted here for security reasons but any one who works in the lab should know it. Once logged in look for Tracking Tools in the start menu or look for the shortcut shown below:
[[Image:TrackingTools_shortcut.PNG|thumb|center|Tracking Tools shortcut]]
Once the program opens the screen should look something like this:
[[Image:NewTrackingTools.PNG|800px]]
In the Tracking Tools Quick Start pop up menu select Open Existing Project and then navigate to ''D:\Optitrack_Configuration'' (It should open to this directory by default) and select the most recent Tracking Tools project. It should be named like ''TrackingToolsProject YYYY-MM-DD timeStamp.ttp''. This is normally the most recently edited file when sorting by data modified. The most recent one as of August 1st, 2016 is ''TrackingToolsProject 2015-09-23 2.30pm.ttp''.
[[Image:OpeningProject.PNG|800px]]
You should notice that the cameras shown in main project scree arrange themselves like out camera configuration once the project has been opened. Now the constellations need to be loaded. This can be done by going to ''File->Open'' and another pop up window will open. Navigate back to ''D:\Optitrack_Configuration'' (It should open to this directory by default) and select the most recently dated set of RADA trackables. They are named like ''RADA_entireSystem_M_D_YYYY.tra''. The most recent one as of August 1st, 2016 is ''RADA_entireSystem_7_8_2016.tra''.
[[Image:Opening_trackables.PNG|800px]]
Once the project and trackless are open the cameras should appear in their constellation (square) and there should be two constellations under ''Project Explorer->Trackables''. One Named UAV for the pendulum and one named ERIS for the ground vehicle. In order to get additional information about each constellation left click on the the name of the desired trackable.
[[Image:SelectingUAV.PNG|800px]]
Once a trackable is selected more information about it is available in the ''Trackables'' Tab on the right side of the screen. For the current position and orientation look at the ''Real-Time Info'' sub-tab. This gives the orientation in the wrong order for how we currently use the Euler angles. When two or three of the angles are near zero you can switch yaw and pitch to get roughly the correct orientation.
[[Image:Uav_realTimeInfo.PNG|800px]]
Now we need check to make sure the system is zeroed.
1. Hold RADA so that the front of the ground robot (ERIS is facing the wall with the white boards (east)). The front side of Eris is labeled. If it isn't it is the side opposite of the switches and the side with the trackable constellation on it.
2. Make sure that the motor with the red motor mount is also facing the wall with the white boards.
3. Make sure the quad system is aligned along Eris Axis by standing behind the system and seeing if you can use the pole to block mounting bolts of the front propeller motor mount when looking at the pole while facing the east wall.
4. While holding the pendulum approximately vertical see if the camera system reads zeros for the pendulum (UAV) pitch and roll (yaw and roll in ''Real-Time Info''). If yaw is off by a few degrees that is fine.
5. Compare the yaw of the UAV to that of ERIS (Remember this is pitch in ''Real-Time Info''). If they are both near zero and with in a few degrees and the pendulum's pitch/roll were also near zero then you are ready to use the camera system. Otherwise go to the next step.
6. You need to zero the pendulum.
- Align ERIS so it is near zero yaw first (eye ball it).
- Get a level and a friend. Have your friend use a level to ensure that the pendulum is level in both directs and hold it there.
- With the UAV constellation selected go to the ''Orientation'' tab (next to ''Real-Time Info'' tab) and click on ''Reset To Current Orientation button''
- Now your friend can set the pendulum down and you can zero ERIS the same way.
7. Save the new trackable orientation by going to ''File->Save Trakables...'' and save a file using the same naming conventions as the trackable file you opened earlier except use the current data so you don't have to re-zero the system the next time you test.
[[Image:Uav_ResetOrientation.PNG|800px]]
=== Building Software ===
The development environment for running RADA is hosted on CO3050-11, a Linux Red Hat environment. This computer has a local ucart user name that you should use. The password isn't put here for security reasons. In order to ensure that the RADA software is setup correctly for the test you want to run. To do this you will need to open the main.cpp and logger.cpp files and make sure all of the compile time macros you want are defined correctly. All of the c++ files you should need to edit are in the directory ''~/Desktop/rada_research_project/ErisResearchCode/CppProjects/MainProgram_PacketLoss/src/Korebot'' Below is a compiler macro options for main.cpp:
-'''H2ctrl''' : This will cause the system to enter H2 controller mode where the whole RADA system is controlled by an H2 controller.
-'''ssTracking''' : H2ctrl must also be defined for this macro to do anything. This macro will has the system to be controlled by a tracking H2 controller.
-'''ssMotors''' : H2ctrl must also be defined for this macro to do anything. This macro will has the system to be controlled by an H2 contorller that contains propeller states. This also cause the system to "Dance."
-'''ssDrop''' : Cause the system to go into packet drop controller mode. This mode allows controllers designed for lossy networks to be tested. Based off of other definitions how lossy the network is can be simulated. If nothing else is defined this controller becomes basically a H2 controller.
-'''drop10''' : Will put the packet drop mode into 10% loss mode and use a controller designed for 10% loss.
-'''drop30''' : Will put the packet drop mode into 30% loss mode and use a controller designed for 30% loss.
-'''drop50''' : Will put the packet drop mode into 50% loss mode and use a controller designed for 50% loss.
-'''mot50''' : This macro over-rides all other macros. If this is turned on the wheels will not run and the propllers will be run at 50% command. This is used for measuring the effective battery voltage seen by the ESCs. This is always run after a test.
-'''RADAlqi''' : This macro will cause the system to use an LQI controller on the whole system. The linear velocity states are calculated with no filter and the angular velocity states are calculated with filters.
-'''RADAlqi_est''' : This macro will cause the system to use an LQI controller on the whole system. A traditional estimator is used to estimate the states.
-'''rada_lqg''' : This macro will cause the entire system to be controlled by a LQG controller/estimator system.
-'''rada_split_lqg''' : This macro will cause the pendulum and ground robot to be controlled by their own LQG systems.
-'''rada_split_lqg_ol''' : This macro will cause the pendulum to be controlled by an LQG controller, the yaw of the ground robot to be controlled by a PID controller, and the ground robot linear velocities to be controlled with open-loop commands.
-'''yaw_off''' : This macro will cause the yaw control to be disabled on some controllers.
*'''accR''' : This macro will cause the PID linear velocity controllers to be given ramps to acclerate from one velocity to another instead of steps.
-'''posRamp''' : This macro will cause the linear velocities of RADA to be controlled by position PIDs with ramp reference instead of velocity commands.
-If no controller selection is made all controllers revert to PID controllers
All of these macros can be defined simply by uncommenting the corresponding define statement in main.cpp. The macros in the logger.cpp can be seen below:
-'''ssDrop''' : This macro puts the logger into packed drop controller mode and logs the correct values for the packet drop controllers.
-'''RADAlqi''' : This macro puts the logger into full system LQI controller logging mode.
-'''RADAlqi_est''' : This macro puts the logger into full system LQI controller plus estimator logging mode.
-'''rada_lqg''' : This puts the logger into full system LQG controller logging mode.
-'''rada_split_lqg''' : This macro causes the logger to log data about the subsystem LQG controllers.
-'''rada_split_lqg_ol''' : This cause the system to log data about the pendulum LQG system and the open-loop linear velocity commands.
-'''H2ctrl''' : This macro causes the logger to log data about the full system H2 controllers.
-If no logging mode is selected then the logger will default to logging PID data.
Because the system only calculates controllers for one set of controllers it is important to ensure that the logger is in the correct mode based off of what is defined in main.cpp. As of August 1st, 2016 the defines in main.cpp are not seen in logger.cpp.
Finally in a command prompt navigate to the driectroy: ''~/Desktop/rada_research_project/ErisResearchCode/CppProjects/MainProgram_PacketLoss''
Here just type: ''make''. The code will compile for your desired mode. For setting up a new development directory see [http://wikis.ece.iastate.edu/robotic-agriculture-data-acquisition/index.php/Setting_up_a_new_development_environment Setting up a new development environment] from the RADA senior Design wiki.
[[Image:ComplingRADACode.png|800px]]
The complied executable code ends up in ''/home/shared/MainProject''. The ''/home/shared'' directory is setup as a network file share (NFS).
[[Image:ErisCompliedCode-config.png|800px]]
This service needs to be restarted when CO3050-11 is restarted. [http://wikis.ece.iastate.edu/robotic-agriculture-data-acquisition/index.php/Configuring_NFS_shares_for_the_robot Configure NFS shares for the robot] from the RADA Senior Design wiki. Be sure to use the new Linux install command in step six. Though I have fond that even on a good strt the ''[ok]'' messages will still print.
=== Turing on RADA ===
Turing on Eris is fairly simple. Each system has its own battery. There is one for the wheels that plugs in at the front of Eris (opposite side of the swiches), one for the electronics in the back of Eris (in between the switches), and one for the propellers that goes on top of Eris.
[[Image:ErisOnPhoto.jpg|800px]]
The wheel battery is normally 1600 mAh 2-cell Lipo but any 2-cell Lipo will work. The wheels are turned on by flipping the silver switch so the top points away from the system. The electronics normally use a 2600 mAh 2-cell Lipo. The electronics are turned on by flipping the green switch away from the system. It is important that you only the WIFI adapter or Ethernet plugged in at the same time or VRPN my listen to the camera data broadcast over both connects which could cause problems. The propeller system is powered via a 2600 mAh 4-cell Lipo that connects to a power cable at the base of the pendulum. There is a switch to turn on the power to the propellers system. You will know it is on when the 1 on the switch is flush with the switch housing instead of sticking out. It takes about 30 seconds to a minute for Eris to boot up and start the networking connections. When the WIFI is plugged in you will know it is ready when a blue light turns on, on the module.
=== Connecting to RADA ===
RADA is controlled through an SSH connection. in a commands prompt, not the one you compile the code from so that you can recompile for different setup with out needing to close the connection. If you are using a WIFI connect use the command ''ssh root@192.168.0.53''. If you are connected to Eris through a LAN connaction use the command ''ssh root@192.168.0.54''. If the connection goes though you should be proped for a password.
The password is ''rootme''.
[[Image:Ssh2Eris.png|800px]]
It is important to close the SSH connection before turning off Eris because the terminal you are using will hang up if you don't. You can close the connection by using the command ''exit''.
[[Image:ClosingSSH.png|800px]]
== Testing RADA ==
Now that you are connected to Eris you can run tests. The testing is started by a few different methods.
=== Running the first test after power up ===
For the firs test after powering on Eris a few additional steps need to be completed in order to test the system. The FPGA motor controller needs to be programmed and Eris needs to connect the the NFS server running on CO3050-11. This is accomplished by running ''1_co3050-11.sh'', this shell scrip will setup the NFS, load the bit file into the FPGA configuration memory. Then it retrieves the executable file from the NFS server ''/mnt/nfs/MainProject and runs the executable. Once the user exits the executable the log file produces is copied from the ''~/Logs/YYYY_MM_DD_Day'' directory on Eris to ''/home/shared/MainProject/Logs/YYYY_MM_DD_Day'' on CO3050-11. When the folder for the current Eris date doesn't exist it creates this directory in CO3050-11 and then removes the directory and log file from Eris. You may see an warning that when coping the log file Eris couldn't maintain the file permisiion settings. This is normal as Eris doesn't have the same access to the NSF server as it has to its own files. This Date stamp uses date on Eris which is currently in June of 2008 as of August 2nd, 2016.
Before starting the test it is best to have someone spotting the pendulum a holding it near vertical so that the pendulum doesn't have issues when entering a control mode.'''<span style="color:red"> Always run ensure the pendulum is spotted by a second person when testing so you don't hurt yourself, others in the lab, or the RADA system.</span>''' Once you spotter is ready run the shell scrip by= using the command ''./1_co3050-11.sh'' in the terminal with the open SSH connection to Eris from the home, ''/root'', directory of Eris. When you run this script there will be a bunch of information printed out about the PIC bus and loading the bit file to configure the FPGA, you will know that RADA is ready for the test when it asks you to select a running mode. See the Testing Modes section below. This script can take a while to complete so beyond the first test after start up you don't need to run this script. See the Section about Running additional tests below.
[[Image:StartingRADA initial.png|800px]]
=== Testing Modes ===
The RADA system has three testing modes: Robot Control Mode, Tuning Mode, and Box Step Mode. Additionally you can exit the execution at any time by pressing the ''Esc'' key. Once the terminal asks you to chose a mode you can use the following commands to enter the desired mode with a three second delay or exit the program. You can also use these commands to switch between the modes.
-''v'' : Enters the pendulum PID tuning mode, this will only really work when using PIDs to control the pendulum.
-''b'' : Enter Robot control mode, in this mode you can drive the robot around and the pendulum will try to stay vertical. This is the main mode used for testing the whole RADA system.
-''n'' : Enters box step mode, where the pendulum will change its desired pitch and roll angles every 20 seconds and move in a box shape.
-''Esc'' : By hitting the escape key the program will exit the program.
You will almost always want to run Robot Control Mode as the other modes are legacy modes from when we initially built and tested RADA and only works with the pendulum PID controllers. There are also a few utility commands that can be used in all modes.
-''2'' : Resets I composts of the Pitch/Roll PIDs and only the PIDs.
-''m'' : Adds a marker to the Log file incase odd things happen somewhere. This just increments a counter so if you use it look for changes in the marker value.
==== Robot Control Model ====
In Robot control mode you can control the motion of Eris. For PID control of Eris or 1D state feedback system the directional commands command Eris body velocity were for full system and Eris system state feedback controllers control the global velocity. All of these keys only need to be pressed not held down.
-''w'' : Moves Eris forward (+x) at some velocity depending on the controller.
-''s'' : Moves Eris in reverse (-x) at some velocity depending on the controller.
-''d'' : Moves Eris in right (+y) at some velocity depending on the controller.
-''a'' : Moves Eris in left (-y) at some velocity depending on the controller.
-''p'' : Stops the motion of Eris (Set all velocity set points to zero). I.e. if you hit ''w'' then hit ''s'' then Eris will be moving in reverse.
-''y'' : Moves Eris forward and to the right (+x/+y) simultaneously at some velocity depending on the controller.
-''t'' : Moves Eris forward and to the left (+x/-y) simultaneously at some velocity depending on the controller.
-''i'' : Moves Eris reverse and to the right (-x/+y) simultaneously at some velocity depending on the controller.
-''y'' : Moves Eris reverse and to the left (-x/-y) simultaneously at some velocity depending on the controller.
-''e'' : Rotate Eris clockwise (+yaw) at some angular rate. This only worked when RADA used the closed-loop FPGA control of the wheels. There is currently no controllers that use this command.
-''q'' : Rotate Eris counter-clockwise (-yaw) at some angular rate. This only worked when RADA used the closed-loop FPGA control of the wheels. There is currently no controllers that use this command.
-''<'' : Increment Eris' desired heading 45 degrees counter-clockwise (-yaw).
-''>'' : Increment Eris' desired heading 45 degrees clockwise (+yaw).
-''7'' : Increments the pitch set point (+pitch).
-''4'' : Decrements the pitch set point (-pitch).
-''8'' : Increments the roll set point (+roll).
-''5'' : Decrements the roll set point (-roll).
==== Tuning Mode ====
Tuning mode allows you to tune the PID controllers for both pitch and roll. The UI commands here are also available in Box Step Mode.
-''1'' : Tune the Pitch PID.
-''3'' : Tune the Roll PID.
-''7'' : Increase proportional gain of PID being tuned.
-''4'' : Decrease proportional gain of PID being tuned.
-''8'' : Increase integral gain of PID being tuned.
-''5'' : Decrease integral gain of PID being tuned.
-''9'' : Increase derivative gain of PID being tuned.
-''6'' : Decrease derivative gain of PID being tuned.
-''i'' : Increase set point of PID being tuned.
-''k'' : Decrease set point of PID being tuned.
-''o'' : Increase integral windup term of PID being tuned. (Not used)
-''l'' : Decrease integral windup term of PID being tuned. (Not used)
==== Box Step Mode ====
Box set mode will automatically change the set points of the pendulum every 20 seconds. The case statement for this mode can be changed for 1D and 2D step modes. This mode allows the user to use he same commands as Tuning Mode.
=== Running additional Tests ===
Once you have run one test with Eris on it is unnecessary to configure the FPGA or connect to the NFS server again. This is what took much of the time in the initial setup. This is what the script ''3_stat_eris.sh'' was developed for. It does everything that ''1_co3050-11.sh'' does but without reprogramming the FPGA or reconnecting to the NFS server. As a result it is ready to test much quicker.
Before starting the test it is best to have someone spotting the pendulum a holding it near vertical so that the pendulum doesn't have issues when entering a control mode.'''<span style="color:red"> Always run ensure the pendulum is spotted by a second person when testing so you don't hurt yourself, others in the lab, or the RADA system.</span>''' Once you spotter is ready run the shell scrip by= using the command ''./3_start_eris.sh'' in the terminal with the open SSH connection to Eris from the home, ''/root'', directory of Eris.
[[Image:StartingRADA2nd.png|800px]]
=== Locating and retrieving log files ===
Once you are done with a test that you want to compare to the model you should retrieve the log file right away so you don't mix it up with other test. On CO3050-11 go to the dircetory ''/home/shared/MainProject/Logs'' using the file browser (you can do this in a terminal but it is easier from the file explorer). Once there, look for the folder that has been modified most recently as Eris date is normally out of sync with its date and time. Then look for the newest log file. Log files are named like ''log(hh.mm.ss).txt'' (ex. log(13.04.51).txt). This naming convention works well to ensure that no log file is over written but it isn't useful of describing what the test was of or for. Copy this log to the Desktop or to a USB drive and rename it. A good method is to name the file something like ''RADA_ctrl_otherNote#.txt'', where Describes what system you tested (ex. RADA, RADA1D, PEN1D, PEN2D), what typ of controller was used, other notes and then a number if this is a repeat of another test. This is much more useful when looking back at these logs later on. Before transferring the log file for processing you should record the wheel and propeller battery voltages in the header of the log file. The log file format is both human readable and can be parsed by MATALB. It was designed by the first RADA Senior Design Team and more information about the log files can be found [http://wikis.ece.iastate.edu/robotic-agriculture-data-acquisition/index.php/Data_Analysis_Tool here.] See he section below on measuring battery voltage below in order to get the best measurements for simulation of RADA.
=== Measuring battery voltages ===
==== Wheel Battery ====
==== Quad Battery ====
== Post processing and Simulation ==
=== Using the MATLAB data parsing tool ===
=== Adding additional data for simulations ===
=== Setting up the MATLAB workspace for simulation ===
=== Running simulations and storing results ===
=== Plotting results ===
43f2a88f6bae58d0f15c79fb0252f8b8809671a9
243
239
2016-08-02T19:55:02Z
Pfuhing
5
/* Measuring battery voltages */
wikitext
text/x-wiki
This page will take you though setting up and testing RADA, retrieving the log file and other necessary data to run a simulation of that test and processing the data in MATLAB. Then actually running the simulation of RADA in Simulink.
== Setting Up a RADA Test ==
Testing RADA is not overly difficult once you get the hang of the steps to setup RADA. The following steps may seem like a long process to go from starting the testing process to having completed simulation and plotting of the test results but this whole test procedure (with the exception of battery charging) can be completed in about 15-20 minutes. These steps are meant to be as detailed as possible in order to help new users of RADA to get up and running as quickly as possible.
'''<span style="color:red">NOTE: Always run RADA with at least 2 people!</span>''' The pendulum arm can crash into the ground if the network starts to drop packets and one person cannot give commands to RADA and spot the pendulum. This is a safety issue for both you and the RADA platform.
=== Charging batteries ===
The lab currently uses mostly Hyperion batteries. We charge our batteries with a Hyperion EOS 1420i Net3 battery charger. For some general information about how to use this charger see [https://www.youtube.com/watch?v=-ox3EpzvsJ8 this video.]. In the lab we power this charger using the old Kepco Power supplu because it is the only power supply that we have that can supply enough current. Make sure that the power supply is set to an output voltage between 10.5V-29V.
{| class="wikitable" style="text-align:center"
|-
| [[Image:ChargerPowerSupplyOff.JPG|400px]]
| [[Image:ChargerPowerSuplyOn.JPG|400px]]
|-
| Kepco Power Supply off.
| Kepco Power Supply on with correct voltage supply range.
|}
While the YouTube video linked above should explain how to use the charger. Currently three different Lithium polymer batteries (Lipo): 1600 mAh 2-cell Lipo for the wheels, 2600 mAh 2-cell Lipo for the electronics of Eris, and a 2600 mAh 4-cell Lipo. The 1600 mAh 2-cell Lipo can be charged using memory slot 2 of the charger. The 2600 mAh 2-cell Lipos can be charged using memory slot 3 for fast charging and memory slot 4 for slower charging (use this if the battery gets run really low for 10-20 minutes then switch to fast charging). The 2600 mAh 4-cell Lipo can be charged using memory slot 8. The 1600 mAh 2-cell and 2600 mAr 4-cell generally charge in 10-20 minutes apiece while I generally fine it takes the 2600 mAh 2-cell up to 70 minutes to charge fully.
=== Setting up the camera system ===
The camera system is run on the windows computer CO3050-07. You can log into this computer using a local microcart username and password which is not posted here for security reasons but any one who works in the lab should know it. Once logged in look for Tracking Tools in the start menu or look for the shortcut shown below:
[[Image:TrackingTools_shortcut.PNG|thumb|center|Tracking Tools shortcut]]
Once the program opens the screen should look something like this:
[[Image:NewTrackingTools.PNG|800px]]
In the Tracking Tools Quick Start pop up menu select Open Existing Project and then navigate to ''D:\Optitrack_Configuration'' (It should open to this directory by default) and select the most recent Tracking Tools project. It should be named like ''TrackingToolsProject YYYY-MM-DD timeStamp.ttp''. This is normally the most recently edited file when sorting by data modified. The most recent one as of August 1st, 2016 is ''TrackingToolsProject 2015-09-23 2.30pm.ttp''.
[[Image:OpeningProject.PNG|800px]]
You should notice that the cameras shown in main project scree arrange themselves like out camera configuration once the project has been opened. Now the constellations need to be loaded. This can be done by going to ''File->Open'' and another pop up window will open. Navigate back to ''D:\Optitrack_Configuration'' (It should open to this directory by default) and select the most recently dated set of RADA trackables. They are named like ''RADA_entireSystem_M_D_YYYY.tra''. The most recent one as of August 1st, 2016 is ''RADA_entireSystem_7_8_2016.tra''.
[[Image:Opening_trackables.PNG|800px]]
Once the project and trackless are open the cameras should appear in their constellation (square) and there should be two constellations under ''Project Explorer->Trackables''. One Named UAV for the pendulum and one named ERIS for the ground vehicle. In order to get additional information about each constellation left click on the the name of the desired trackable.
[[Image:SelectingUAV.PNG|800px]]
Once a trackable is selected more information about it is available in the ''Trackables'' Tab on the right side of the screen. For the current position and orientation look at the ''Real-Time Info'' sub-tab. This gives the orientation in the wrong order for how we currently use the Euler angles. When two or three of the angles are near zero you can switch yaw and pitch to get roughly the correct orientation.
[[Image:Uav_realTimeInfo.PNG|800px]]
Now we need check to make sure the system is zeroed.
1. Hold RADA so that the front of the ground robot (ERIS is facing the wall with the white boards (east)). The front side of Eris is labeled. If it isn't it is the side opposite of the switches and the side with the trackable constellation on it.
2. Make sure that the motor with the red motor mount is also facing the wall with the white boards.
3. Make sure the quad system is aligned along Eris Axis by standing behind the system and seeing if you can use the pole to block mounting bolts of the front propeller motor mount when looking at the pole while facing the east wall.
4. While holding the pendulum approximately vertical see if the camera system reads zeros for the pendulum (UAV) pitch and roll (yaw and roll in ''Real-Time Info''). If yaw is off by a few degrees that is fine.
5. Compare the yaw of the UAV to that of ERIS (Remember this is pitch in ''Real-Time Info''). If they are both near zero and with in a few degrees and the pendulum's pitch/roll were also near zero then you are ready to use the camera system. Otherwise go to the next step.
6. You need to zero the pendulum.
- Align ERIS so it is near zero yaw first (eye ball it).
- Get a level and a friend. Have your friend use a level to ensure that the pendulum is level in both directs and hold it there.
- With the UAV constellation selected go to the ''Orientation'' tab (next to ''Real-Time Info'' tab) and click on ''Reset To Current Orientation button''
- Now your friend can set the pendulum down and you can zero ERIS the same way.
7. Save the new trackable orientation by going to ''File->Save Trakables...'' and save a file using the same naming conventions as the trackable file you opened earlier except use the current data so you don't have to re-zero the system the next time you test.
[[Image:Uav_ResetOrientation.PNG|800px]]
=== Building Software ===
The development environment for running RADA is hosted on CO3050-11, a Linux Red Hat environment. This computer has a local ucart user name that you should use. The password isn't put here for security reasons. In order to ensure that the RADA software is setup correctly for the test you want to run. To do this you will need to open the main.cpp and logger.cpp files and make sure all of the compile time macros you want are defined correctly. All of the c++ files you should need to edit are in the directory ''~/Desktop/rada_research_project/ErisResearchCode/CppProjects/MainProgram_PacketLoss/src/Korebot'' Below is a compiler macro options for main.cpp:
-'''H2ctrl''' : This will cause the system to enter H2 controller mode where the whole RADA system is controlled by an H2 controller.
-'''ssTracking''' : H2ctrl must also be defined for this macro to do anything. This macro will has the system to be controlled by a tracking H2 controller.
-'''ssMotors''' : H2ctrl must also be defined for this macro to do anything. This macro will has the system to be controlled by an H2 contorller that contains propeller states. This also cause the system to "Dance."
-'''ssDrop''' : Cause the system to go into packet drop controller mode. This mode allows controllers designed for lossy networks to be tested. Based off of other definitions how lossy the network is can be simulated. If nothing else is defined this controller becomes basically a H2 controller.
-'''drop10''' : Will put the packet drop mode into 10% loss mode and use a controller designed for 10% loss.
-'''drop30''' : Will put the packet drop mode into 30% loss mode and use a controller designed for 30% loss.
-'''drop50''' : Will put the packet drop mode into 50% loss mode and use a controller designed for 50% loss.
-'''mot50''' : This macro over-rides all other macros. If this is turned on the wheels will not run and the propllers will be run at 50% command. This is used for measuring the effective battery voltage seen by the ESCs. This is always run after a test.
-'''RADAlqi''' : This macro will cause the system to use an LQI controller on the whole system. The linear velocity states are calculated with no filter and the angular velocity states are calculated with filters.
-'''RADAlqi_est''' : This macro will cause the system to use an LQI controller on the whole system. A traditional estimator is used to estimate the states.
-'''rada_lqg''' : This macro will cause the entire system to be controlled by a LQG controller/estimator system.
-'''rada_split_lqg''' : This macro will cause the pendulum and ground robot to be controlled by their own LQG systems.
-'''rada_split_lqg_ol''' : This macro will cause the pendulum to be controlled by an LQG controller, the yaw of the ground robot to be controlled by a PID controller, and the ground robot linear velocities to be controlled with open-loop commands.
-'''yaw_off''' : This macro will cause the yaw control to be disabled on some controllers.
*'''accR''' : This macro will cause the PID linear velocity controllers to be given ramps to acclerate from one velocity to another instead of steps.
-'''posRamp''' : This macro will cause the linear velocities of RADA to be controlled by position PIDs with ramp reference instead of velocity commands.
-If no controller selection is made all controllers revert to PID controllers
All of these macros can be defined simply by uncommenting the corresponding define statement in main.cpp. The macros in the logger.cpp can be seen below:
-'''ssDrop''' : This macro puts the logger into packed drop controller mode and logs the correct values for the packet drop controllers.
-'''RADAlqi''' : This macro puts the logger into full system LQI controller logging mode.
-'''RADAlqi_est''' : This macro puts the logger into full system LQI controller plus estimator logging mode.
-'''rada_lqg''' : This puts the logger into full system LQG controller logging mode.
-'''rada_split_lqg''' : This macro causes the logger to log data about the subsystem LQG controllers.
-'''rada_split_lqg_ol''' : This cause the system to log data about the pendulum LQG system and the open-loop linear velocity commands.
-'''H2ctrl''' : This macro causes the logger to log data about the full system H2 controllers.
-If no logging mode is selected then the logger will default to logging PID data.
Because the system only calculates controllers for one set of controllers it is important to ensure that the logger is in the correct mode based off of what is defined in main.cpp. As of August 1st, 2016 the defines in main.cpp are not seen in logger.cpp.
Finally in a command prompt navigate to the driectroy: ''~/Desktop/rada_research_project/ErisResearchCode/CppProjects/MainProgram_PacketLoss''
Here just type: ''make''. The code will compile for your desired mode. For setting up a new development directory see [http://wikis.ece.iastate.edu/robotic-agriculture-data-acquisition/index.php/Setting_up_a_new_development_environment Setting up a new development environment] from the RADA senior Design wiki.
[[Image:ComplingRADACode.png|800px]]
The complied executable code ends up in ''/home/shared/MainProject''. The ''/home/shared'' directory is setup as a network file share (NFS).
[[Image:ErisCompliedCode-config.png|800px]]
This service needs to be restarted when CO3050-11 is restarted. [http://wikis.ece.iastate.edu/robotic-agriculture-data-acquisition/index.php/Configuring_NFS_shares_for_the_robot Configure NFS shares for the robot] from the RADA Senior Design wiki. Be sure to use the new Linux install command in step six. Though I have fond that even on a good strt the ''[ok]'' messages will still print.
=== Turing on RADA ===
Turing on Eris is fairly simple. Each system has its own battery. There is one for the wheels that plugs in at the front of Eris (opposite side of the swiches), one for the electronics in the back of Eris (in between the switches), and one for the propellers that goes on top of Eris.
[[Image:ErisOnPhoto.jpg|800px]]
The wheel battery is normally 1600 mAh 2-cell Lipo but any 2-cell Lipo will work. The wheels are turned on by flipping the silver switch so the top points away from the system. The electronics normally use a 2600 mAh 2-cell Lipo. The electronics are turned on by flipping the green switch away from the system. It is important that you only the WIFI adapter or Ethernet plugged in at the same time or VRPN my listen to the camera data broadcast over both connects which could cause problems. The propeller system is powered via a 2600 mAh 4-cell Lipo that connects to a power cable at the base of the pendulum. There is a switch to turn on the power to the propellers system. You will know it is on when the 1 on the switch is flush with the switch housing instead of sticking out. It takes about 30 seconds to a minute for Eris to boot up and start the networking connections. When the WIFI is plugged in you will know it is ready when a blue light turns on, on the module.
=== Connecting to RADA ===
RADA is controlled through an SSH connection. in a commands prompt, not the one you compile the code from so that you can recompile for different setup with out needing to close the connection. If you are using a WIFI connect use the command ''ssh root@192.168.0.53''. If you are connected to Eris through a LAN connaction use the command ''ssh root@192.168.0.54''. If the connection goes though you should be proped for a password.
The password is ''rootme''.
[[Image:Ssh2Eris.png|800px]]
It is important to close the SSH connection before turning off Eris because the terminal you are using will hang up if you don't. You can close the connection by using the command ''exit''.
[[Image:ClosingSSH.png|800px]]
== Testing RADA ==
Now that you are connected to Eris you can run tests. The testing is started by a few different methods.
=== Running the first test after power up ===
For the firs test after powering on Eris a few additional steps need to be completed in order to test the system. The FPGA motor controller needs to be programmed and Eris needs to connect the the NFS server running on CO3050-11. This is accomplished by running ''1_co3050-11.sh'', this shell scrip will setup the NFS, load the bit file into the FPGA configuration memory. Then it retrieves the executable file from the NFS server ''/mnt/nfs/MainProject and runs the executable. Once the user exits the executable the log file produces is copied from the ''~/Logs/YYYY_MM_DD_Day'' directory on Eris to ''/home/shared/MainProject/Logs/YYYY_MM_DD_Day'' on CO3050-11. When the folder for the current Eris date doesn't exist it creates this directory in CO3050-11 and then removes the directory and log file from Eris. You may see an warning that when coping the log file Eris couldn't maintain the file permisiion settings. This is normal as Eris doesn't have the same access to the NSF server as it has to its own files. This Date stamp uses date on Eris which is currently in June of 2008 as of August 2nd, 2016.
Before starting the test it is best to have someone spotting the pendulum a holding it near vertical so that the pendulum doesn't have issues when entering a control mode.'''<span style="color:red"> Always run ensure the pendulum is spotted by a second person when testing so you don't hurt yourself, others in the lab, or the RADA system.</span>''' Once you spotter is ready run the shell scrip by= using the command ''./1_co3050-11.sh'' in the terminal with the open SSH connection to Eris from the home, ''/root'', directory of Eris. When you run this script there will be a bunch of information printed out about the PIC bus and loading the bit file to configure the FPGA, you will know that RADA is ready for the test when it asks you to select a running mode. See the Testing Modes section below. This script can take a while to complete so beyond the first test after start up you don't need to run this script. See the Section about Running additional tests below.
[[Image:StartingRADA initial.png|800px]]
=== Testing Modes ===
The RADA system has three testing modes: Robot Control Mode, Tuning Mode, and Box Step Mode. Additionally you can exit the execution at any time by pressing the ''Esc'' key. Once the terminal asks you to chose a mode you can use the following commands to enter the desired mode with a three second delay or exit the program. You can also use these commands to switch between the modes.
-''v'' : Enters the pendulum PID tuning mode, this will only really work when using PIDs to control the pendulum.
-''b'' : Enter Robot control mode, in this mode you can drive the robot around and the pendulum will try to stay vertical. This is the main mode used for testing the whole RADA system.
-''n'' : Enters box step mode, where the pendulum will change its desired pitch and roll angles every 20 seconds and move in a box shape.
-''Esc'' : By hitting the escape key the program will exit the program.
You will almost always want to run Robot Control Mode as the other modes are legacy modes from when we initially built and tested RADA and only works with the pendulum PID controllers. There are also a few utility commands that can be used in all modes.
-''2'' : Resets I composts of the Pitch/Roll PIDs and only the PIDs.
-''m'' : Adds a marker to the Log file incase odd things happen somewhere. This just increments a counter so if you use it look for changes in the marker value.
==== Robot Control Model ====
In Robot control mode you can control the motion of Eris. For PID control of Eris or 1D state feedback system the directional commands command Eris body velocity were for full system and Eris system state feedback controllers control the global velocity. All of these keys only need to be pressed not held down.
-''w'' : Moves Eris forward (+x) at some velocity depending on the controller.
-''s'' : Moves Eris in reverse (-x) at some velocity depending on the controller.
-''d'' : Moves Eris in right (+y) at some velocity depending on the controller.
-''a'' : Moves Eris in left (-y) at some velocity depending on the controller.
-''p'' : Stops the motion of Eris (Set all velocity set points to zero). I.e. if you hit ''w'' then hit ''s'' then Eris will be moving in reverse.
-''y'' : Moves Eris forward and to the right (+x/+y) simultaneously at some velocity depending on the controller.
-''t'' : Moves Eris forward and to the left (+x/-y) simultaneously at some velocity depending on the controller.
-''i'' : Moves Eris reverse and to the right (-x/+y) simultaneously at some velocity depending on the controller.
-''y'' : Moves Eris reverse and to the left (-x/-y) simultaneously at some velocity depending on the controller.
-''e'' : Rotate Eris clockwise (+yaw) at some angular rate. This only worked when RADA used the closed-loop FPGA control of the wheels. There is currently no controllers that use this command.
-''q'' : Rotate Eris counter-clockwise (-yaw) at some angular rate. This only worked when RADA used the closed-loop FPGA control of the wheels. There is currently no controllers that use this command.
-''<'' : Increment Eris' desired heading 45 degrees counter-clockwise (-yaw).
-''>'' : Increment Eris' desired heading 45 degrees clockwise (+yaw).
-''7'' : Increments the pitch set point (+pitch).
-''4'' : Decrements the pitch set point (-pitch).
-''8'' : Increments the roll set point (+roll).
-''5'' : Decrements the roll set point (-roll).
==== Tuning Mode ====
Tuning mode allows you to tune the PID controllers for both pitch and roll. The UI commands here are also available in Box Step Mode.
-''1'' : Tune the Pitch PID.
-''3'' : Tune the Roll PID.
-''7'' : Increase proportional gain of PID being tuned.
-''4'' : Decrease proportional gain of PID being tuned.
-''8'' : Increase integral gain of PID being tuned.
-''5'' : Decrease integral gain of PID being tuned.
-''9'' : Increase derivative gain of PID being tuned.
-''6'' : Decrease derivative gain of PID being tuned.
-''i'' : Increase set point of PID being tuned.
-''k'' : Decrease set point of PID being tuned.
-''o'' : Increase integral windup term of PID being tuned. (Not used)
-''l'' : Decrease integral windup term of PID being tuned. (Not used)
==== Box Step Mode ====
Box set mode will automatically change the set points of the pendulum every 20 seconds. The case statement for this mode can be changed for 1D and 2D step modes. This mode allows the user to use he same commands as Tuning Mode.
=== Running additional Tests ===
Once you have run one test with Eris on it is unnecessary to configure the FPGA or connect to the NFS server again. This is what took much of the time in the initial setup. This is what the script ''3_stat_eris.sh'' was developed for. It does everything that ''1_co3050-11.sh'' does but without reprogramming the FPGA or reconnecting to the NFS server. As a result it is ready to test much quicker.
Before starting the test it is best to have someone spotting the pendulum a holding it near vertical so that the pendulum doesn't have issues when entering a control mode.'''<span style="color:red"> Always run ensure the pendulum is spotted by a second person when testing so you don't hurt yourself, others in the lab, or the RADA system.</span>''' Once you spotter is ready run the shell scrip by= using the command ''./3_start_eris.sh'' in the terminal with the open SSH connection to Eris from the home, ''/root'', directory of Eris.
[[Image:StartingRADA2nd.png|800px]]
=== Locating and retrieving log files ===
Once you are done with a test that you want to compare to the model you should retrieve the log file right away so you don't mix it up with other test. On CO3050-11 go to the dircetory ''/home/shared/MainProject/Logs'' using the file browser (you can do this in a terminal but it is easier from the file explorer). Once there, look for the folder that has been modified most recently as Eris date is normally out of sync with its date and time. Then look for the newest log file. Log files are named like ''log(hh.mm.ss).txt'' (ex. log(13.04.51).txt). This naming convention works well to ensure that no log file is over written but it isn't useful of describing what the test was of or for. Copy this log to the Desktop or to a USB drive and rename it. A good method is to name the file something like ''RADA_ctrl_otherNote#.txt'', where Describes what system you tested (ex. RADA, RADA1D, PEN1D, PEN2D), what typ of controller was used, other notes and then a number if this is a repeat of another test. This is much more useful when looking back at these logs later on. Before transferring the log file for processing you should record the wheel and propeller battery voltages in the header of the log file. The log file format is both human readable and can be parsed by MATALB. It was designed by the first RADA Senior Design Team and more information about the log files can be found [http://wikis.ece.iastate.edu/robotic-agriculture-data-acquisition/index.php/Data_Analysis_Tool here.] See he section below on measuring battery voltage below in order to get the best measurements for simulation of RADA.
=== Measuring battery voltages ===
The last thing that you need to do before simulating an experiment of the RADA platform is record the battery voltages for both the wheels and propellers. The wheel battery can be measured unloaded as there isn't large line losses between the battery and the H-bridges. The propeller battery voltage needs to be measured under load because the power cord running up the pendulum has significant line losses at the currents the propellers draw when in use. The battery voltages can be recorded in the log file for the test. Open the log file for the test you just completed (Use KWrite for Linux machines or Notepad++ for Windows machines). The first few lines of the log is the headder. It should look like this:
#Constants pitch_P pitch_I pitch_D
#PIDValues 48000 18000 21000
#Constants roll_P roll_I roll_D
#PIDValues 48000 18000 21000
#Battery Vquad Vwheels
#Voltage
Follow the procedure for measuring the voltage of each battery and then record the voltage under the corresponding battery. Then save the log file and close out of your text editor and the test will be ready for processing. Recoding the battery voltages in this way makes it much easier to find if you need the value latter. The final log file header should look like this once you are done
#Constants pitch_P pitch_I pitch_D
#PIDValues 48000 18000 21000
#Constants roll_P roll_I roll_D
#PIDValues 48000 18000 21000
#Battery Vquad Vwheels
#Voltage 14.44 8.257
==== Wheel Battery ====
==== Quad Battery ====
== Post processing and Simulation ==
=== Using the MATLAB data parsing tool ===
=== Adding additional data for simulations ===
=== Setting up the MATLAB workspace for simulation ===
=== Running simulations and storing results ===
=== Plotting results ===
2577eed86f07236e35eeb5657ff5bda849a8418b
249
243
2016-08-02T20:05:41Z
Pfuhing
5
/* Wheel Battery */
wikitext
text/x-wiki
This page will take you though setting up and testing RADA, retrieving the log file and other necessary data to run a simulation of that test and processing the data in MATLAB. Then actually running the simulation of RADA in Simulink.
== Setting Up a RADA Test ==
Testing RADA is not overly difficult once you get the hang of the steps to setup RADA. The following steps may seem like a long process to go from starting the testing process to having completed simulation and plotting of the test results but this whole test procedure (with the exception of battery charging) can be completed in about 15-20 minutes. These steps are meant to be as detailed as possible in order to help new users of RADA to get up and running as quickly as possible.
'''<span style="color:red">NOTE: Always run RADA with at least 2 people!</span>''' The pendulum arm can crash into the ground if the network starts to drop packets and one person cannot give commands to RADA and spot the pendulum. This is a safety issue for both you and the RADA platform.
=== Charging batteries ===
The lab currently uses mostly Hyperion batteries. We charge our batteries with a Hyperion EOS 1420i Net3 battery charger. For some general information about how to use this charger see [https://www.youtube.com/watch?v=-ox3EpzvsJ8 this video.]. In the lab we power this charger using the old Kepco Power supplu because it is the only power supply that we have that can supply enough current. Make sure that the power supply is set to an output voltage between 10.5V-29V.
{| class="wikitable" style="text-align:center"
|-
| [[Image:ChargerPowerSupplyOff.JPG|400px]]
| [[Image:ChargerPowerSuplyOn.JPG|400px]]
|-
| Kepco Power Supply off.
| Kepco Power Supply on with correct voltage supply range.
|}
While the YouTube video linked above should explain how to use the charger. Currently three different Lithium polymer batteries (Lipo): 1600 mAh 2-cell Lipo for the wheels, 2600 mAh 2-cell Lipo for the electronics of Eris, and a 2600 mAh 4-cell Lipo. The 1600 mAh 2-cell Lipo can be charged using memory slot 2 of the charger. The 2600 mAh 2-cell Lipos can be charged using memory slot 3 for fast charging and memory slot 4 for slower charging (use this if the battery gets run really low for 10-20 minutes then switch to fast charging). The 2600 mAh 4-cell Lipo can be charged using memory slot 8. The 1600 mAh 2-cell and 2600 mAr 4-cell generally charge in 10-20 minutes apiece while I generally fine it takes the 2600 mAh 2-cell up to 70 minutes to charge fully.
=== Setting up the camera system ===
The camera system is run on the windows computer CO3050-07. You can log into this computer using a local microcart username and password which is not posted here for security reasons but any one who works in the lab should know it. Once logged in look for Tracking Tools in the start menu or look for the shortcut shown below:
[[Image:TrackingTools_shortcut.PNG|thumb|center|Tracking Tools shortcut]]
Once the program opens the screen should look something like this:
[[Image:NewTrackingTools.PNG|800px]]
In the Tracking Tools Quick Start pop up menu select Open Existing Project and then navigate to ''D:\Optitrack_Configuration'' (It should open to this directory by default) and select the most recent Tracking Tools project. It should be named like ''TrackingToolsProject YYYY-MM-DD timeStamp.ttp''. This is normally the most recently edited file when sorting by data modified. The most recent one as of August 1st, 2016 is ''TrackingToolsProject 2015-09-23 2.30pm.ttp''.
[[Image:OpeningProject.PNG|800px]]
You should notice that the cameras shown in main project scree arrange themselves like out camera configuration once the project has been opened. Now the constellations need to be loaded. This can be done by going to ''File->Open'' and another pop up window will open. Navigate back to ''D:\Optitrack_Configuration'' (It should open to this directory by default) and select the most recently dated set of RADA trackables. They are named like ''RADA_entireSystem_M_D_YYYY.tra''. The most recent one as of August 1st, 2016 is ''RADA_entireSystem_7_8_2016.tra''.
[[Image:Opening_trackables.PNG|800px]]
Once the project and trackless are open the cameras should appear in their constellation (square) and there should be two constellations under ''Project Explorer->Trackables''. One Named UAV for the pendulum and one named ERIS for the ground vehicle. In order to get additional information about each constellation left click on the the name of the desired trackable.
[[Image:SelectingUAV.PNG|800px]]
Once a trackable is selected more information about it is available in the ''Trackables'' Tab on the right side of the screen. For the current position and orientation look at the ''Real-Time Info'' sub-tab. This gives the orientation in the wrong order for how we currently use the Euler angles. When two or three of the angles are near zero you can switch yaw and pitch to get roughly the correct orientation.
[[Image:Uav_realTimeInfo.PNG|800px]]
Now we need check to make sure the system is zeroed.
1. Hold RADA so that the front of the ground robot (ERIS is facing the wall with the white boards (east)). The front side of Eris is labeled. If it isn't it is the side opposite of the switches and the side with the trackable constellation on it.
2. Make sure that the motor with the red motor mount is also facing the wall with the white boards.
3. Make sure the quad system is aligned along Eris Axis by standing behind the system and seeing if you can use the pole to block mounting bolts of the front propeller motor mount when looking at the pole while facing the east wall.
4. While holding the pendulum approximately vertical see if the camera system reads zeros for the pendulum (UAV) pitch and roll (yaw and roll in ''Real-Time Info''). If yaw is off by a few degrees that is fine.
5. Compare the yaw of the UAV to that of ERIS (Remember this is pitch in ''Real-Time Info''). If they are both near zero and with in a few degrees and the pendulum's pitch/roll were also near zero then you are ready to use the camera system. Otherwise go to the next step.
6. You need to zero the pendulum.
- Align ERIS so it is near zero yaw first (eye ball it).
- Get a level and a friend. Have your friend use a level to ensure that the pendulum is level in both directs and hold it there.
- With the UAV constellation selected go to the ''Orientation'' tab (next to ''Real-Time Info'' tab) and click on ''Reset To Current Orientation button''
- Now your friend can set the pendulum down and you can zero ERIS the same way.
7. Save the new trackable orientation by going to ''File->Save Trakables...'' and save a file using the same naming conventions as the trackable file you opened earlier except use the current data so you don't have to re-zero the system the next time you test.
[[Image:Uav_ResetOrientation.PNG|800px]]
=== Building Software ===
The development environment for running RADA is hosted on CO3050-11, a Linux Red Hat environment. This computer has a local ucart user name that you should use. The password isn't put here for security reasons. In order to ensure that the RADA software is setup correctly for the test you want to run. To do this you will need to open the main.cpp and logger.cpp files and make sure all of the compile time macros you want are defined correctly. All of the c++ files you should need to edit are in the directory ''~/Desktop/rada_research_project/ErisResearchCode/CppProjects/MainProgram_PacketLoss/src/Korebot'' Below is a compiler macro options for main.cpp:
-'''H2ctrl''' : This will cause the system to enter H2 controller mode where the whole RADA system is controlled by an H2 controller.
-'''ssTracking''' : H2ctrl must also be defined for this macro to do anything. This macro will has the system to be controlled by a tracking H2 controller.
-'''ssMotors''' : H2ctrl must also be defined for this macro to do anything. This macro will has the system to be controlled by an H2 contorller that contains propeller states. This also cause the system to "Dance."
-'''ssDrop''' : Cause the system to go into packet drop controller mode. This mode allows controllers designed for lossy networks to be tested. Based off of other definitions how lossy the network is can be simulated. If nothing else is defined this controller becomes basically a H2 controller.
-'''drop10''' : Will put the packet drop mode into 10% loss mode and use a controller designed for 10% loss.
-'''drop30''' : Will put the packet drop mode into 30% loss mode and use a controller designed for 30% loss.
-'''drop50''' : Will put the packet drop mode into 50% loss mode and use a controller designed for 50% loss.
-'''mot50''' : This macro over-rides all other macros. If this is turned on the wheels will not run and the propllers will be run at 50% command. This is used for measuring the effective battery voltage seen by the ESCs. This is always run after a test.
-'''RADAlqi''' : This macro will cause the system to use an LQI controller on the whole system. The linear velocity states are calculated with no filter and the angular velocity states are calculated with filters.
-'''RADAlqi_est''' : This macro will cause the system to use an LQI controller on the whole system. A traditional estimator is used to estimate the states.
-'''rada_lqg''' : This macro will cause the entire system to be controlled by a LQG controller/estimator system.
-'''rada_split_lqg''' : This macro will cause the pendulum and ground robot to be controlled by their own LQG systems.
-'''rada_split_lqg_ol''' : This macro will cause the pendulum to be controlled by an LQG controller, the yaw of the ground robot to be controlled by a PID controller, and the ground robot linear velocities to be controlled with open-loop commands.
-'''yaw_off''' : This macro will cause the yaw control to be disabled on some controllers.
*'''accR''' : This macro will cause the PID linear velocity controllers to be given ramps to acclerate from one velocity to another instead of steps.
-'''posRamp''' : This macro will cause the linear velocities of RADA to be controlled by position PIDs with ramp reference instead of velocity commands.
-If no controller selection is made all controllers revert to PID controllers
All of these macros can be defined simply by uncommenting the corresponding define statement in main.cpp. The macros in the logger.cpp can be seen below:
-'''ssDrop''' : This macro puts the logger into packed drop controller mode and logs the correct values for the packet drop controllers.
-'''RADAlqi''' : This macro puts the logger into full system LQI controller logging mode.
-'''RADAlqi_est''' : This macro puts the logger into full system LQI controller plus estimator logging mode.
-'''rada_lqg''' : This puts the logger into full system LQG controller logging mode.
-'''rada_split_lqg''' : This macro causes the logger to log data about the subsystem LQG controllers.
-'''rada_split_lqg_ol''' : This cause the system to log data about the pendulum LQG system and the open-loop linear velocity commands.
-'''H2ctrl''' : This macro causes the logger to log data about the full system H2 controllers.
-If no logging mode is selected then the logger will default to logging PID data.
Because the system only calculates controllers for one set of controllers it is important to ensure that the logger is in the correct mode based off of what is defined in main.cpp. As of August 1st, 2016 the defines in main.cpp are not seen in logger.cpp.
Finally in a command prompt navigate to the driectroy: ''~/Desktop/rada_research_project/ErisResearchCode/CppProjects/MainProgram_PacketLoss''
Here just type: ''make''. The code will compile for your desired mode. For setting up a new development directory see [http://wikis.ece.iastate.edu/robotic-agriculture-data-acquisition/index.php/Setting_up_a_new_development_environment Setting up a new development environment] from the RADA senior Design wiki.
[[Image:ComplingRADACode.png|800px]]
The complied executable code ends up in ''/home/shared/MainProject''. The ''/home/shared'' directory is setup as a network file share (NFS).
[[Image:ErisCompliedCode-config.png|800px]]
This service needs to be restarted when CO3050-11 is restarted. [http://wikis.ece.iastate.edu/robotic-agriculture-data-acquisition/index.php/Configuring_NFS_shares_for_the_robot Configure NFS shares for the robot] from the RADA Senior Design wiki. Be sure to use the new Linux install command in step six. Though I have fond that even on a good strt the ''[ok]'' messages will still print.
=== Turing on RADA ===
Turing on Eris is fairly simple. Each system has its own battery. There is one for the wheels that plugs in at the front of Eris (opposite side of the swiches), one for the electronics in the back of Eris (in between the switches), and one for the propellers that goes on top of Eris.
[[Image:ErisOnPhoto.jpg|800px]]
The wheel battery is normally 1600 mAh 2-cell Lipo but any 2-cell Lipo will work. The wheels are turned on by flipping the silver switch so the top points away from the system. The electronics normally use a 2600 mAh 2-cell Lipo. The electronics are turned on by flipping the green switch away from the system. It is important that you only the WIFI adapter or Ethernet plugged in at the same time or VRPN my listen to the camera data broadcast over both connects which could cause problems. The propeller system is powered via a 2600 mAh 4-cell Lipo that connects to a power cable at the base of the pendulum. There is a switch to turn on the power to the propellers system. You will know it is on when the 1 on the switch is flush with the switch housing instead of sticking out. It takes about 30 seconds to a minute for Eris to boot up and start the networking connections. When the WIFI is plugged in you will know it is ready when a blue light turns on, on the module.
=== Connecting to RADA ===
RADA is controlled through an SSH connection. in a commands prompt, not the one you compile the code from so that you can recompile for different setup with out needing to close the connection. If you are using a WIFI connect use the command ''ssh root@192.168.0.53''. If you are connected to Eris through a LAN connaction use the command ''ssh root@192.168.0.54''. If the connection goes though you should be proped for a password.
The password is ''rootme''.
[[Image:Ssh2Eris.png|800px]]
It is important to close the SSH connection before turning off Eris because the terminal you are using will hang up if you don't. You can close the connection by using the command ''exit''.
[[Image:ClosingSSH.png|800px]]
== Testing RADA ==
Now that you are connected to Eris you can run tests. The testing is started by a few different methods.
=== Running the first test after power up ===
For the firs test after powering on Eris a few additional steps need to be completed in order to test the system. The FPGA motor controller needs to be programmed and Eris needs to connect the the NFS server running on CO3050-11. This is accomplished by running ''1_co3050-11.sh'', this shell scrip will setup the NFS, load the bit file into the FPGA configuration memory. Then it retrieves the executable file from the NFS server ''/mnt/nfs/MainProject and runs the executable. Once the user exits the executable the log file produces is copied from the ''~/Logs/YYYY_MM_DD_Day'' directory on Eris to ''/home/shared/MainProject/Logs/YYYY_MM_DD_Day'' on CO3050-11. When the folder for the current Eris date doesn't exist it creates this directory in CO3050-11 and then removes the directory and log file from Eris. You may see an warning that when coping the log file Eris couldn't maintain the file permisiion settings. This is normal as Eris doesn't have the same access to the NSF server as it has to its own files. This Date stamp uses date on Eris which is currently in June of 2008 as of August 2nd, 2016.
Before starting the test it is best to have someone spotting the pendulum a holding it near vertical so that the pendulum doesn't have issues when entering a control mode.'''<span style="color:red"> Always run ensure the pendulum is spotted by a second person when testing so you don't hurt yourself, others in the lab, or the RADA system.</span>''' Once you spotter is ready run the shell scrip by= using the command ''./1_co3050-11.sh'' in the terminal with the open SSH connection to Eris from the home, ''/root'', directory of Eris. When you run this script there will be a bunch of information printed out about the PIC bus and loading the bit file to configure the FPGA, you will know that RADA is ready for the test when it asks you to select a running mode. See the Testing Modes section below. This script can take a while to complete so beyond the first test after start up you don't need to run this script. See the Section about Running additional tests below.
[[Image:StartingRADA initial.png|800px]]
=== Testing Modes ===
The RADA system has three testing modes: Robot Control Mode, Tuning Mode, and Box Step Mode. Additionally you can exit the execution at any time by pressing the ''Esc'' key. Once the terminal asks you to chose a mode you can use the following commands to enter the desired mode with a three second delay or exit the program. You can also use these commands to switch between the modes.
-''v'' : Enters the pendulum PID tuning mode, this will only really work when using PIDs to control the pendulum.
-''b'' : Enter Robot control mode, in this mode you can drive the robot around and the pendulum will try to stay vertical. This is the main mode used for testing the whole RADA system.
-''n'' : Enters box step mode, where the pendulum will change its desired pitch and roll angles every 20 seconds and move in a box shape.
-''Esc'' : By hitting the escape key the program will exit the program.
You will almost always want to run Robot Control Mode as the other modes are legacy modes from when we initially built and tested RADA and only works with the pendulum PID controllers. There are also a few utility commands that can be used in all modes.
-''2'' : Resets I composts of the Pitch/Roll PIDs and only the PIDs.
-''m'' : Adds a marker to the Log file incase odd things happen somewhere. This just increments a counter so if you use it look for changes in the marker value.
==== Robot Control Model ====
In Robot control mode you can control the motion of Eris. For PID control of Eris or 1D state feedback system the directional commands command Eris body velocity were for full system and Eris system state feedback controllers control the global velocity. All of these keys only need to be pressed not held down.
-''w'' : Moves Eris forward (+x) at some velocity depending on the controller.
-''s'' : Moves Eris in reverse (-x) at some velocity depending on the controller.
-''d'' : Moves Eris in right (+y) at some velocity depending on the controller.
-''a'' : Moves Eris in left (-y) at some velocity depending on the controller.
-''p'' : Stops the motion of Eris (Set all velocity set points to zero). I.e. if you hit ''w'' then hit ''s'' then Eris will be moving in reverse.
-''y'' : Moves Eris forward and to the right (+x/+y) simultaneously at some velocity depending on the controller.
-''t'' : Moves Eris forward and to the left (+x/-y) simultaneously at some velocity depending on the controller.
-''i'' : Moves Eris reverse and to the right (-x/+y) simultaneously at some velocity depending on the controller.
-''y'' : Moves Eris reverse and to the left (-x/-y) simultaneously at some velocity depending on the controller.
-''e'' : Rotate Eris clockwise (+yaw) at some angular rate. This only worked when RADA used the closed-loop FPGA control of the wheels. There is currently no controllers that use this command.
-''q'' : Rotate Eris counter-clockwise (-yaw) at some angular rate. This only worked when RADA used the closed-loop FPGA control of the wheels. There is currently no controllers that use this command.
-''<'' : Increment Eris' desired heading 45 degrees counter-clockwise (-yaw).
-''>'' : Increment Eris' desired heading 45 degrees clockwise (+yaw).
-''7'' : Increments the pitch set point (+pitch).
-''4'' : Decrements the pitch set point (-pitch).
-''8'' : Increments the roll set point (+roll).
-''5'' : Decrements the roll set point (-roll).
==== Tuning Mode ====
Tuning mode allows you to tune the PID controllers for both pitch and roll. The UI commands here are also available in Box Step Mode.
-''1'' : Tune the Pitch PID.
-''3'' : Tune the Roll PID.
-''7'' : Increase proportional gain of PID being tuned.
-''4'' : Decrease proportional gain of PID being tuned.
-''8'' : Increase integral gain of PID being tuned.
-''5'' : Decrease integral gain of PID being tuned.
-''9'' : Increase derivative gain of PID being tuned.
-''6'' : Decrease derivative gain of PID being tuned.
-''i'' : Increase set point of PID being tuned.
-''k'' : Decrease set point of PID being tuned.
-''o'' : Increase integral windup term of PID being tuned. (Not used)
-''l'' : Decrease integral windup term of PID being tuned. (Not used)
==== Box Step Mode ====
Box set mode will automatically change the set points of the pendulum every 20 seconds. The case statement for this mode can be changed for 1D and 2D step modes. This mode allows the user to use he same commands as Tuning Mode.
=== Running additional Tests ===
Once you have run one test with Eris on it is unnecessary to configure the FPGA or connect to the NFS server again. This is what took much of the time in the initial setup. This is what the script ''3_stat_eris.sh'' was developed for. It does everything that ''1_co3050-11.sh'' does but without reprogramming the FPGA or reconnecting to the NFS server. As a result it is ready to test much quicker.
Before starting the test it is best to have someone spotting the pendulum a holding it near vertical so that the pendulum doesn't have issues when entering a control mode.'''<span style="color:red"> Always run ensure the pendulum is spotted by a second person when testing so you don't hurt yourself, others in the lab, or the RADA system.</span>''' Once you spotter is ready run the shell scrip by= using the command ''./3_start_eris.sh'' in the terminal with the open SSH connection to Eris from the home, ''/root'', directory of Eris.
[[Image:StartingRADA2nd.png|800px]]
=== Locating and retrieving log files ===
Once you are done with a test that you want to compare to the model you should retrieve the log file right away so you don't mix it up with other test. On CO3050-11 go to the dircetory ''/home/shared/MainProject/Logs'' using the file browser (you can do this in a terminal but it is easier from the file explorer). Once there, look for the folder that has been modified most recently as Eris date is normally out of sync with its date and time. Then look for the newest log file. Log files are named like ''log(hh.mm.ss).txt'' (ex. log(13.04.51).txt). This naming convention works well to ensure that no log file is over written but it isn't useful of describing what the test was of or for. Copy this log to the Desktop or to a USB drive and rename it. A good method is to name the file something like ''RADA_ctrl_otherNote#.txt'', where Describes what system you tested (ex. RADA, RADA1D, PEN1D, PEN2D), what typ of controller was used, other notes and then a number if this is a repeat of another test. This is much more useful when looking back at these logs later on. Before transferring the log file for processing you should record the wheel and propeller battery voltages in the header of the log file. The log file format is both human readable and can be parsed by MATALB. It was designed by the first RADA Senior Design Team and more information about the log files can be found [http://wikis.ece.iastate.edu/robotic-agriculture-data-acquisition/index.php/Data_Analysis_Tool here.] See he section below on measuring battery voltage below in order to get the best measurements for simulation of RADA.
=== Measuring battery voltages ===
The last thing that you need to do before simulating an experiment of the RADA platform is record the battery voltages for both the wheels and propellers. The wheel battery can be measured unloaded as there isn't large line losses between the battery and the H-bridges. The propeller battery voltage needs to be measured under load because the power cord running up the pendulum has significant line losses at the currents the propellers draw when in use. The battery voltages can be recorded in the log file for the test. Open the log file for the test you just completed (Use KWrite for Linux machines or Notepad++ for Windows machines). The first few lines of the log is the headder. It should look like this:
#Constants pitch_P pitch_I pitch_D
#PIDValues 48000 18000 21000
#Constants roll_P roll_I roll_D
#PIDValues 48000 18000 21000
#Battery Vquad Vwheels
#Voltage
Follow the procedure for measuring the voltage of each battery and then record the voltage under the corresponding battery. Then save the log file and close out of your text editor and the test will be ready for processing. Recoding the battery voltages in this way makes it much easier to find if you need the value latter. The final log file header should look like this once you are done
#Constants pitch_P pitch_I pitch_D
#PIDValues 48000 18000 21000
#Constants roll_P roll_I roll_D
#PIDValues 48000 18000 21000
#Battery Vquad Vwheels
#Voltage 14.44 8.257
==== Wheel Battery ====
1. After test disconnect wheel battery from the system.
2. Measure voltage of battery using multimeter.
[[Image:MeasureVwheel.jpg|800px]]
You can use the plug used for charging the 2-cell Lipos but make sure to connect the plug to the multimeter before connecting the battery and disconnect the battery before disconnecting the plug from the mulitmeter. It is generally the best practice to give the multimeter a few minutes to allow for the voltage measurement to stabilize as the battery measurement tends to be a little low right after the test.
==== Quad Battery ====
== Post processing and Simulation ==
=== Using the MATLAB data parsing tool ===
=== Adding additional data for simulations ===
=== Setting up the MATLAB workspace for simulation ===
=== Running simulations and storing results ===
=== Plotting results ===
874f3d9a7b563544a89f055673a46f05df21093c
File:ComplingRADACode.png
6
60
212
2016-08-02T01:43:07Z
Pfuhing
5
compile RADA code
wikitext
text/x-wiki
compile RADA code
e90628876cdd10f06ddb3e57033cf69feb7c7652
File:ErisCompliedCode-config.png
6
61
213
2016-08-02T01:43:41Z
Pfuhing
5
wikitext
text/x-wiki
da39a3ee5e6b4b0d3255bfef95601890afd80709
File:ErisOnPhoto.jpg
6
62
216
2016-08-02T01:55:05Z
Pfuhing
5
wikitext
text/x-wiki
da39a3ee5e6b4b0d3255bfef95601890afd80709
File:Ssh2Eris.png
6
63
219
2016-08-02T02:12:31Z
Pfuhing
5
wikitext
text/x-wiki
da39a3ee5e6b4b0d3255bfef95601890afd80709
File:ClosingSSH.png
6
64
220
2016-08-02T02:14:34Z
Pfuhing
5
wikitext
text/x-wiki
da39a3ee5e6b4b0d3255bfef95601890afd80709
PC Client Software
0
25
223
163
2016-08-02T16:38:32Z
Jnoronha
3
/* Crazyflie Client GUI */ added crazyflie client file path
wikitext
text/x-wiki
The PC Client software comes in many forms. The out-of-the-box Client is written in Python and has a Graphical User Interface (GUI). The GUI is well suited for beginners, but can only support a single Radio and a single Crazyflie at a time. The easiest way to start out is with the [https://wiki.bitcraze.io/projects:virtualmachine:index Bitcraze Virtual Machine (VM)], which comes with all the files and dependencies pre-installed and can run on any computer (Windows, Mac, Linux, etc.).
For more advanced users who want to use the swarm capabilities of our platform will have to use the [[#Swarm Client|Swarm Client]] we developed in C and C++.
==[https://wiki.bitcraze.io/projects:virtualmachine:index Bitcraze VM]==
('''Note:''' The VM is updated frequently so the information below may be different than the current VM)
The Bitcraze wiki has a tutorial on [https://wiki.bitcraze.io/projects:virtualmachine:tutorials:vmware-win7 installing the VM]. Along with another tutorial on how to get started [https://www.bitcraze.io/getting-started-with-development/ using the VM].
These are both very simple starting guides that will help you become familiar with the VM.
===Crazyflie Client GUI===
On the VM you can find the Crazyflie Client Graphical User Interface (GUI). To run the Client you want to open a terminal and navigate to <code>/home/bitcraze/Desktop/projects/crazyflie-clients-python/</code> and then run the command <code>sudo ./bin/cfclient</code>
(Alternatively, you can use the desktop to navigate to the folder and open a terminal there)
Once you do that you should see something similar to this:
[[Image:DefaultCrazyflieGUIMainScreen.JPG|500px]]
This is the main screen of the Client GUI and there are many tabs and features that you can access directly from this screen.
The most important parts of this screen are the following:
#Connect Button
#Bootloader (Crazyflie Drop Down -> Bootloader)
#Plotter Tab
#Log Blocks Tab
#Parameters Tab
====Connect Button====
This is where you will scan for Crazyflies that are powered ON. All Crazyflies not already connected will show up in the popup
[[Image:DefaultCrazyflieGUIConnectScreen.JPG|400px]]
We get a return that says <code>radio://0/45/2M</code>, this line is the identifier string of the Crazyflie we are trying to connect to.
What this is saying is that we got a return from a Radio (Radio 0 specifically), from a Crazyflie on Channel 45 using a data rate of 2Mbps.
====Bootloader====
This where you can install new Firmware to the Crazyflie.
[[Image:DefaultCrazyflieGUIBootloader.JPG|500px]]
The first thing you'll need to update is to build the Firmware version you want into a .bin file. You can do this by just running the <code>make</code> command in terminal while located inside the Firmware directory you have modified.
Once you have that .bin file built you:
#Open the bootloader shown
#Hold down the power button on the Crazyflie 2.0 for around 3 seconds until the 2 blue LED's flash and alternate. This puts the Crazyflie in bootloader mode. ('''NOTE:''' Recommend having '''ALL other Crazyflies OFF''' or else it could accidentally flash both Crazyflies.)
#Then hit ''Initiate bootloader cold boot'' (it should connect to the Crazyflie in bootloader mode after a few seconds, Status will change from 'Not Connected' to 'Connected')
#Hit ''Browse'' and find the .bin file you built earlier.
#Then click ''Program'' and wait for the progress bar to complete.
#Restart the Crazyflie in Firmware mode and make sure it starts up normally, if something seems wrong just repeat steps 2 through 6 again.
====Logging Tab====
Once you connect to a Crazyflie you can monitor certain log variables that have been set up. You will see a plot of the data similar to this:
[[Image:DefaultCrazyflieGUILoggerScreen.JPG|400px]]
On this screen we can do the following things:
*Dropdown Menu at the top of the screen
**Select which log block you want to plot on screen.
*Scale the X-axis of the plot by:
**Range
**Number of Samples
**Time in Seconds
**Manually
*Scale the Y-axis by:
**Automatically
**Manual Range
====Parameters Tab====
This tab displays all the parameters currently set up on the Crazyflie Firmware. Once you connect to a Crazyflie it lists these parameters in a table format similar to below:
[[Image:DefaultCrazyflieGUIParametersScreen.JPG|400px]]
For each parameter we get its Name, Variable Type, Access Type (Read/Write), and its Current Value.
We can also modify the parameter values on this screen in real-time and the changes will be sent to the Crazyflie automatically.
('''Note:''' Any parameter changes made on this screen are NOT preserved when you turn OFF the Crazyflie.)
==Swarm Client==
The swarm Client is a re-creation of the Original Client but programmed in C and C++.
The benefit of this is that
*We use a unified language between Client and Firmware
*Easily migrate this platform to any linux distribution that can install the Crazyflie dependencies.
**Our platform code itself requires only the VRPN libraries and a generic C compiler.
===Using the Swarm Client===
The Swarm Client uses the terminal interface for User Input.
[[Image:CrazyflieTerminalInitial.png|400px]]
Here we see what the initial Terminal looks like before we do anything.
:1. The first thing you want to do before any testing is to run the <code>sudo make</code> command in the Swarm Client directory. (Yes, the 'sudo' is necessary)
::This will make sure you have all the necessary dependencies, that the code is error free, and then it will build an executable (.exe) file of the Swarm Client code. An error free make will look something like this:
::[[Image:CrazyflieTerminalPostMake.png|400px]]
::There will be warnings, but those don't cause any issues right now.
:2. Pre-Test Checklist
::*Camera System is Turned on and Crazyflie Trackables are opened and visible.
::*Radios are plugged into the USB Ports on the Client computer.
::*Crazyflies are ON and NOT in an Error State.
:3. Run the executable file using the command <code>sudo ./eris_vrpn</code> in the same directory (Yes, the 'sudo' is necessary). This will start the program initialization and a bunch of status info will flood the screen. You will know the program is ready for input when you see the following:
::[[Image:CrazyflieTerminalProgramStarted.png|400px]]
::This means that the Crazyflie yaw has been synchronized with the Camera system and they are ready to fly.
:4. Input a Keyboard Command
::This will depend on what you have programmed as the keyboard input commands. As of 7/19/16 we have the following Keyboard Commands active:
::*'1' - Rotates Yaw of Crazyflie1 +45 degrees
::*'2' - Rotates Yaw of Crazyflie1 -45 degrees
::*'q' - Ends Main Loop (OBSOLETE - Replaced with ctrl + c)
::*'e' - Landing Mode (for ALL Crazyflies)
::*'t' - Crazyflie1 Take-Off
::*'y' - Crazyflie2 Take-Off
::*'u' - Crazyflie3 Take-Off
::*'i' - Crazyflie4 Take-Off
::*'h' - Hand Gesture Mode (for ALL Crazyflies)
::*'m' - Mirror Mode (for ALL Crazyflies)
::*ctrl+c - Quits Program, performs all cleanup.
::An example of what this would look like in the Terminal is shown here:
::[[Image:CrazyflieTerminalKeyboardInput.png|400px]]
::So you can see we commanded all 4 Crazyflies to take off (t,y,u,i), then activated Landing Mode (e), then activated Hand Mode (h), and then Ended the Program (ctrl+c).
:5. End Program when finished (ctrl+c)
::This will end the program loop, print the current battery levels, and Delete the Radio pointers (shown at the end of the previous figure)
===Makefile===
The Swarm Client is compiled by a simple makefile. So when you call ''sudo make'' this makefile converts the C++ code files into an executable (.exe) for us.
<blockquote>
<code>
<pre>
g++ = g++ -Wall
all: eris_vrpn
eris_vrpn: eris_vrpn.h eris_vrpn.cpp vrpn.h vrpn.cpp CCrazyflie.h CCrazyflie.cpp
CCrazyRadio.h CCrazyRadio.cpp CCRTPPacket.h CCRTPPacket.cpp CTOC.h CTOC.cpp
simple.cpp simple.h pid.h pid.c controller.h controller.c multicast.c
$(g++) -g -O0 -o eris_vrpn eris_vrpn.cpp vrpn.cpp CCrazyflie.cpp
CCrazyRadio.cpp CCRTPPacket.cpp CTOC.cpp simple.cpp pid.c controller.c
multicast.c -lquat -lvrpn -lpthread -lusb-1.0
clean:
rm -f *.o eris_vrpn
</pre>
</code>
</blockquote>
----
<center> '''Main Directory''' </center>
<center> [[Crazyflie Swarm|Crazyflie Swarm Home]] | [[PC Client Software]] | [[USB Radio]] | [[Firmware]] | [[FAQ]] </center>
<center> '''Modifications Directory''' </center>
<center> [[Controller]] | [[Logging]] | [[Keyboard Commands]] | [[USB Radio#Changing Radio Channel|Changing Radio Channel]] | [[Flight Modes]] | [[Callbacks]] | [[Adding a Crazyflie]] | [[Firmware]] </center>
a916a689881266eefae2c979116065ff9b62532e
224
223
2016-08-02T16:43:22Z
Jnoronha
3
/* Connect Button */ modified return description to a list
wikitext
text/x-wiki
The PC Client software comes in many forms. The out-of-the-box Client is written in Python and has a Graphical User Interface (GUI). The GUI is well suited for beginners, but can only support a single Radio and a single Crazyflie at a time. The easiest way to start out is with the [https://wiki.bitcraze.io/projects:virtualmachine:index Bitcraze Virtual Machine (VM)], which comes with all the files and dependencies pre-installed and can run on any computer (Windows, Mac, Linux, etc.).
For more advanced users who want to use the swarm capabilities of our platform will have to use the [[#Swarm Client|Swarm Client]] we developed in C and C++.
==[https://wiki.bitcraze.io/projects:virtualmachine:index Bitcraze VM]==
('''Note:''' The VM is updated frequently so the information below may be different than the current VM)
The Bitcraze wiki has a tutorial on [https://wiki.bitcraze.io/projects:virtualmachine:tutorials:vmware-win7 installing the VM]. Along with another tutorial on how to get started [https://www.bitcraze.io/getting-started-with-development/ using the VM].
These are both very simple starting guides that will help you become familiar with the VM.
===Crazyflie Client GUI===
On the VM you can find the Crazyflie Client Graphical User Interface (GUI). To run the Client you want to open a terminal and navigate to <code>/home/bitcraze/Desktop/projects/crazyflie-clients-python/</code> and then run the command <code>sudo ./bin/cfclient</code>
(Alternatively, you can use the desktop to navigate to the folder and open a terminal there)
Once you do that you should see something similar to this:
[[Image:DefaultCrazyflieGUIMainScreen.JPG|500px]]
This is the main screen of the Client GUI and there are many tabs and features that you can access directly from this screen.
The most important parts of this screen are the following:
#Connect Button
#Bootloader (Crazyflie Drop Down -> Bootloader)
#Plotter Tab
#Log Blocks Tab
#Parameters Tab
====Connect Button====
This is where you will scan for Crazyflies that are powered ON. All Crazyflies not already connected will show up in the popup
[[Image:DefaultCrazyflieGUIConnectScreen.JPG|400px]]
We get a return that says <code>radio://0/45/2M</code>, this line is the identifier string of the Crazyflie we are trying to connect to.
What this is saying is that we got a return from:
#Radio 0 (the first radio)
#Crazyflie on Channel 45
#Using a data rate of 2Mbps
====Bootloader====
This where you can install new Firmware to the Crazyflie.
[[Image:DefaultCrazyflieGUIBootloader.JPG|500px]]
The first thing you'll need to update is to build the Firmware version you want into a .bin file. You can do this by just running the <code>make</code> command in terminal while located inside the Firmware directory you have modified.
Once you have that .bin file built you:
#Open the bootloader shown
#Hold down the power button on the Crazyflie 2.0 for around 3 seconds until the 2 blue LED's flash and alternate. This puts the Crazyflie in bootloader mode. ('''NOTE:''' Recommend having '''ALL other Crazyflies OFF''' or else it could accidentally flash both Crazyflies.)
#Then hit ''Initiate bootloader cold boot'' (it should connect to the Crazyflie in bootloader mode after a few seconds, Status will change from 'Not Connected' to 'Connected')
#Hit ''Browse'' and find the .bin file you built earlier.
#Then click ''Program'' and wait for the progress bar to complete.
#Restart the Crazyflie in Firmware mode and make sure it starts up normally, if something seems wrong just repeat steps 2 through 6 again.
====Logging Tab====
Once you connect to a Crazyflie you can monitor certain log variables that have been set up. You will see a plot of the data similar to this:
[[Image:DefaultCrazyflieGUILoggerScreen.JPG|400px]]
On this screen we can do the following things:
*Dropdown Menu at the top of the screen
**Select which log block you want to plot on screen.
*Scale the X-axis of the plot by:
**Range
**Number of Samples
**Time in Seconds
**Manually
*Scale the Y-axis by:
**Automatically
**Manual Range
====Parameters Tab====
This tab displays all the parameters currently set up on the Crazyflie Firmware. Once you connect to a Crazyflie it lists these parameters in a table format similar to below:
[[Image:DefaultCrazyflieGUIParametersScreen.JPG|400px]]
For each parameter we get its Name, Variable Type, Access Type (Read/Write), and its Current Value.
We can also modify the parameter values on this screen in real-time and the changes will be sent to the Crazyflie automatically.
('''Note:''' Any parameter changes made on this screen are NOT preserved when you turn OFF the Crazyflie.)
==Swarm Client==
The swarm Client is a re-creation of the Original Client but programmed in C and C++.
The benefit of this is that
*We use a unified language between Client and Firmware
*Easily migrate this platform to any linux distribution that can install the Crazyflie dependencies.
**Our platform code itself requires only the VRPN libraries and a generic C compiler.
===Using the Swarm Client===
The Swarm Client uses the terminal interface for User Input.
[[Image:CrazyflieTerminalInitial.png|400px]]
Here we see what the initial Terminal looks like before we do anything.
:1. The first thing you want to do before any testing is to run the <code>sudo make</code> command in the Swarm Client directory. (Yes, the 'sudo' is necessary)
::This will make sure you have all the necessary dependencies, that the code is error free, and then it will build an executable (.exe) file of the Swarm Client code. An error free make will look something like this:
::[[Image:CrazyflieTerminalPostMake.png|400px]]
::There will be warnings, but those don't cause any issues right now.
:2. Pre-Test Checklist
::*Camera System is Turned on and Crazyflie Trackables are opened and visible.
::*Radios are plugged into the USB Ports on the Client computer.
::*Crazyflies are ON and NOT in an Error State.
:3. Run the executable file using the command <code>sudo ./eris_vrpn</code> in the same directory (Yes, the 'sudo' is necessary). This will start the program initialization and a bunch of status info will flood the screen. You will know the program is ready for input when you see the following:
::[[Image:CrazyflieTerminalProgramStarted.png|400px]]
::This means that the Crazyflie yaw has been synchronized with the Camera system and they are ready to fly.
:4. Input a Keyboard Command
::This will depend on what you have programmed as the keyboard input commands. As of 7/19/16 we have the following Keyboard Commands active:
::*'1' - Rotates Yaw of Crazyflie1 +45 degrees
::*'2' - Rotates Yaw of Crazyflie1 -45 degrees
::*'q' - Ends Main Loop (OBSOLETE - Replaced with ctrl + c)
::*'e' - Landing Mode (for ALL Crazyflies)
::*'t' - Crazyflie1 Take-Off
::*'y' - Crazyflie2 Take-Off
::*'u' - Crazyflie3 Take-Off
::*'i' - Crazyflie4 Take-Off
::*'h' - Hand Gesture Mode (for ALL Crazyflies)
::*'m' - Mirror Mode (for ALL Crazyflies)
::*ctrl+c - Quits Program, performs all cleanup.
::An example of what this would look like in the Terminal is shown here:
::[[Image:CrazyflieTerminalKeyboardInput.png|400px]]
::So you can see we commanded all 4 Crazyflies to take off (t,y,u,i), then activated Landing Mode (e), then activated Hand Mode (h), and then Ended the Program (ctrl+c).
:5. End Program when finished (ctrl+c)
::This will end the program loop, print the current battery levels, and Delete the Radio pointers (shown at the end of the previous figure)
===Makefile===
The Swarm Client is compiled by a simple makefile. So when you call ''sudo make'' this makefile converts the C++ code files into an executable (.exe) for us.
<blockquote>
<code>
<pre>
g++ = g++ -Wall
all: eris_vrpn
eris_vrpn: eris_vrpn.h eris_vrpn.cpp vrpn.h vrpn.cpp CCrazyflie.h CCrazyflie.cpp
CCrazyRadio.h CCrazyRadio.cpp CCRTPPacket.h CCRTPPacket.cpp CTOC.h CTOC.cpp
simple.cpp simple.h pid.h pid.c controller.h controller.c multicast.c
$(g++) -g -O0 -o eris_vrpn eris_vrpn.cpp vrpn.cpp CCrazyflie.cpp
CCrazyRadio.cpp CCRTPPacket.cpp CTOC.cpp simple.cpp pid.c controller.c
multicast.c -lquat -lvrpn -lpthread -lusb-1.0
clean:
rm -f *.o eris_vrpn
</pre>
</code>
</blockquote>
----
<center> '''Main Directory''' </center>
<center> [[Crazyflie Swarm|Crazyflie Swarm Home]] | [[PC Client Software]] | [[USB Radio]] | [[Firmware]] | [[FAQ]] </center>
<center> '''Modifications Directory''' </center>
<center> [[Controller]] | [[Logging]] | [[Keyboard Commands]] | [[USB Radio#Changing Radio Channel|Changing Radio Channel]] | [[Flight Modes]] | [[Callbacks]] | [[Adding a Crazyflie]] | [[Firmware]] </center>
feeeaa521b431d71ff98bcfe34e34d5055badc18
File:StartingRADA initial.png
6
65
226
2016-08-02T17:23:04Z
Pfuhing
5
wikitext
text/x-wiki
da39a3ee5e6b4b0d3255bfef95601890afd80709
File:StartingRADA2nd.png
6
66
227
2016-08-02T17:23:34Z
Pfuhing
5
wikitext
text/x-wiki
da39a3ee5e6b4b0d3255bfef95601890afd80709
Firmware
0
26
228
125
2016-08-02T17:23:36Z
Jnoronha
3
/* Changing Yaw Mode in Firmware */ added yaw mode change modification code
wikitext
text/x-wiki
Not much work has been done in the Firmware yet (as of 7/20/16). The few things we have been able to successfully modify are:
#Creating New Log Blocks
#Modifying the Default Yaw Mode
#Adding and Modifying Parameter Values
==New Firmware Log Blocks==
In the Crazyflie Firmware there is a generalized logging framework that allows us to make any group of variables into a log block. It makes things very easy to log. Here are a few examples:
:'''IMPORTANT:''' If you want to create new Log groups in a file, make sure you include <code>#include "log.h"</code> at the top of the file.
:Ex. 1. Magnometer Log Block (code found in ''Firmware > modules > src > stabilizer.c'')
<blockquote>
<code>
<pre>
LOG_GROUP_START(mag)
LOG_ADD(LOG_FLOAT, x, &mag.x)
LOG_ADD(LOG_FLOAT, y, &mag.y)
LOG_ADD(LOG_FLOAT, z, &mag.z)
LOG_GROUP_STOP(mag)
</pre>
</code>
</blockquote>
::So with this code we have created a log block called 'mag' and it contains the X, Y, and Z measurements from the magnetometer sensor.
:Ex. 2. Accelerometer Log Block (code found in ''Firmware > modules > src > stabilizer.c'')
<blockquote>
<code>
<pre>
LOG_GROUP_START(acc)
LOG_ADD(LOG_FLOAT, x, &acc.x)
LOG_ADD(LOG_FLOAT, y, &acc.y)
LOG_ADD(LOG_FLOAT, z, &acc.z)
LOG_ADD(LOG_FLOAT, zw, &accWZ)
LOG_ADD(LOG_FLOAT, mag2, &accMAG)
LOG_GROUP_STOP(acc)
</pre>
</code>
</blockquote>
::Just like in the magnetometer block, here we have created a log group called 'acc' and inside this group we are logging the variables for the accelerometer's X, Y, and Z values as well as 2 other gravity based variables used for thrust compensation.
===Using New Log Blocks in Swarm Client===
Now that we have these new log blocks in the Firmware, we can [[:Logging#New Client Log Blocks|use log blocks in the Client]]
==Modify the Default Yaw Mode==
There are 3 types of Yaw Modes available in the Firmware (as of 7/21/16), as shown (code in ''Firmware > modules > interface > commander.h'')
<blockquote>
<code>
<pre>
typedef enum
{
CAREFREE = 0, // Yaw is locked to world coordinates thus heading stays the same when yaw rotates
PLUSMODE = 1, // Plus-mode. Motor M1 is defined as front
XMODE = 2, // X-mode. M1 & M4 is defined as front
} YawModeType;
</pre>
</code>
</blockquote>
:'''Note:''' The default mode for the Crazyflie 2.0 is ''XMODE''. The ''PLUSMODE'' is default for the Crazyflie 1.0, but can still be used on the Crazyflie 2.0 if desired.
===Carefree Mode===
''CAREFREE'' mode is what our Crazyflie 2.0's are using, this mode applies a transformation to the Pitch and Roll setpoints depending on the angle of Yaw. We used to perform this calculation on the Client like this (code in ''eris_vrpn.cpp''):
<blockquote>
<code>
<pre>
#if USE_PR_YAW_CORRECT
//CORRECTS PITCH AND ROLL PID ERRORS TO ACCOUNT FOR QUADS CURRENT YAW DIRECTION (_/57.2958 converts DEG to RADIANS)
xError2 = cos(correctedYaw2 / 57.2958)*(xPositionDesired2 - xPosition2) - sin(correctedYaw2 / 57.2958)*(yPositionDesired2 - yPosition2);
yError2 = sin(correctedYaw2 / 57.2958)*(xPositionDesired2 - xPosition2) + cos(correctedYaw2 / 57.2958)*(yPositionDesired2 - yPosition2);
#else
xError2 = xPositionDesired2 - xPosition2;
yError2 = yPositionDesired2 - yPosition2;
#endif
controllerSetXYError(&pidCtrl2, xError2, yError2);
</pre>
</code>
</blockquote>
This is no longer necessary on the Client because this is the exact same calculation ''CAREFREE'' mode performs on the Firmware. So this reduces the computation done on the Client in each Crazyflie Callback.
====Changing Yaw Mode in Firmware====
To change the Yaw Mode to ''CAREFREE'' mode we had to make the modification shown (code in ''Firmware > modules > interface > commander.h (line 36)''):
:'''ORIGINAL:'''
<blockquote>
<code>
<pre>
#ifdef PLATFORM_CF1
#define DEFUALT_YAW_MODE PLUSMODE
#else
#define DEFUALT_YAW_MODE XMODE
#endif
</pre>
</code>
</blockquote>
:'''MODIFIED:'''
<blockquote>
<code>
<pre>
#ifdef PLATFORM_CF1
#define DEFUALT_YAW_MODE PLUSMODE
#else
#define DEFUALT_YAW_MODE CAREFREE
#endif
</pre>
</code>
</blockquote>
::The code checks for which version Crazyflie you are using, either the original Crazyflie (<code>PLATFORM_CF1</code>), or the Crazyflie 2.0. We are using the Crazyflie 2.0 so we only care about the 2nd ''DEFAULT_YAW_MODE'', which we modified to ''CAREFREE'' mode as shown.
==New Firmware Parameter Groups==
Parameter groups are very similar to Log groups with a few key differences. An example of a Parameter group is shown (code in ''Firmware > modules > src > commander.c''):
:'''IMPORTANT:''' If you want to create new Parameter groups in a file, make sure you include <code>#include "param.h"</code> at the top of the file.
<blockquote>
<code>
<pre>
// Params for flight modes
PARAM_GROUP_START(flightmode)
PARAM_ADD(PARAM_UINT8, althold, &altHoldMode)
PARAM_ADD(PARAM_UINT8, yawMode, &yawMode)
PARAM_ADD(PARAM_UINT8, yawRst, &carefreeResetFront)
PARAM_ADD(PARAM_UINT8, stabModeRoll, &stabilizationModeRoll)
PARAM_ADD(PARAM_UINT8, stabModePitch, &stabilizationModePitch)
PARAM_ADD(PARAM_UINT8, stabModeYaw, &stabilizationModeYaw)
PARAM_GROUP_STOP(flightmode)
</pre>
</code>
</blockquote>
:So we create a parameter group called ''flightmode'' that contains the parameters listed. The difference between Log variables and Param variables is that for Param variables you need to specify the variable type (''PARAM_UINT8'' shown in the example).
Some User Friendly Param Types are shown below (you can find more complex Param types in ''Firmware > modules > interface > param.h'').
<blockquote>
<code>
<pre>
// User-friendly macros
#define PARAM_UINT8 (PARAM_1BYTE | PARAM_TYPE_INT | PARAM_UNSIGNED)
#define PARAM_INT8 (PARAM_1BYTE | PARAM_TYPE_INT | PARAM_SIGNED)
#define PARAM_UINT16 (PARAM_2BYTES | PARAM_TYPE_INT | PARAM_UNSIGNED)
#define PARAM_INT16 (PARAM_2BYTES | PARAM_TYPE_INT | PARAM_SIGNED)
#define PARAM_UINT32 (PARAM_4BYTES | PARAM_TYPE_INT | PARAM_UNSIGNED)
#define PARAM_INT32 (PARAM_4BYTES | PARAM_TYPE_INT | PARAM_SIGNED)
</pre>
</code>
</blockquote>
===Using Param Groups in Client===
This is not implemented yet (as of 7/21/16) but would be very nice to have. We could then tune Firmware PID constants without needing to flash the Firmware each time and much more.
If someone would like to attempt to create this you can see the Bitcraze Wiki page on the [https://wiki.bitcraze.io/doc:crazyflie:crtp:param Params Protocol] for help on how to implement this.
----
<center> '''Main Directory''' </center>
<center> [[Crazyflie Swarm|Crazyflie Swarm Home]] | [[PC Client Software]] | [[USB Radio]] | [[Firmware]] | [[FAQ]] </center>
<center> '''Modifications Directory''' </center>
<center> [[Controller]] | [[Logging]] | [[Keyboard Commands]] | [[USB Radio#Changing Radio Channel|Changing Radio Channel]] | [[Flight Modes]] | [[Callbacks]] | [[Adding a Crazyflie]] | [[Firmware]] </center>
7feba85e4864c2dcc99100e9c3587155c8cbd601
247
228
2016-08-02T20:01:13Z
Jnoronha
3
/* Changing Yaw Mode in Firmware */ added ellipses to yaw mode firmware change to show its a code section
wikitext
text/x-wiki
Not much work has been done in the Firmware yet (as of 7/20/16). The few things we have been able to successfully modify are:
#Creating New Log Blocks
#Modifying the Default Yaw Mode
#Adding and Modifying Parameter Values
==New Firmware Log Blocks==
In the Crazyflie Firmware there is a generalized logging framework that allows us to make any group of variables into a log block. It makes things very easy to log. Here are a few examples:
:'''IMPORTANT:''' If you want to create new Log groups in a file, make sure you include <code>#include "log.h"</code> at the top of the file.
:Ex. 1. Magnometer Log Block (code found in ''Firmware > modules > src > stabilizer.c'')
<blockquote>
<code>
<pre>
LOG_GROUP_START(mag)
LOG_ADD(LOG_FLOAT, x, &mag.x)
LOG_ADD(LOG_FLOAT, y, &mag.y)
LOG_ADD(LOG_FLOAT, z, &mag.z)
LOG_GROUP_STOP(mag)
</pre>
</code>
</blockquote>
::So with this code we have created a log block called 'mag' and it contains the X, Y, and Z measurements from the magnetometer sensor.
:Ex. 2. Accelerometer Log Block (code found in ''Firmware > modules > src > stabilizer.c'')
<blockquote>
<code>
<pre>
LOG_GROUP_START(acc)
LOG_ADD(LOG_FLOAT, x, &acc.x)
LOG_ADD(LOG_FLOAT, y, &acc.y)
LOG_ADD(LOG_FLOAT, z, &acc.z)
LOG_ADD(LOG_FLOAT, zw, &accWZ)
LOG_ADD(LOG_FLOAT, mag2, &accMAG)
LOG_GROUP_STOP(acc)
</pre>
</code>
</blockquote>
::Just like in the magnetometer block, here we have created a log group called 'acc' and inside this group we are logging the variables for the accelerometer's X, Y, and Z values as well as 2 other gravity based variables used for thrust compensation.
===Using New Log Blocks in Swarm Client===
Now that we have these new log blocks in the Firmware, we can [[:Logging#New Client Log Blocks|use log blocks in the Client]]
==Modify the Default Yaw Mode==
There are 3 types of Yaw Modes available in the Firmware (as of 7/21/16), as shown (code in ''Firmware > modules > interface > commander.h'')
<blockquote>
<code>
<pre>
typedef enum
{
CAREFREE = 0, // Yaw is locked to world coordinates thus heading stays the same when yaw rotates
PLUSMODE = 1, // Plus-mode. Motor M1 is defined as front
XMODE = 2, // X-mode. M1 & M4 is defined as front
} YawModeType;
</pre>
</code>
</blockquote>
:'''Note:''' The default mode for the Crazyflie 2.0 is ''XMODE''. The ''PLUSMODE'' is default for the Crazyflie 1.0, but can still be used on the Crazyflie 2.0 if desired.
===Carefree Mode===
''CAREFREE'' mode is what our Crazyflie 2.0's are using, this mode applies a transformation to the Pitch and Roll setpoints depending on the angle of Yaw. We used to perform this calculation on the Client like this (code in ''eris_vrpn.cpp''):
<blockquote>
<code>
<pre>
#if USE_PR_YAW_CORRECT
//CORRECTS PITCH AND ROLL PID ERRORS TO ACCOUNT FOR QUADS CURRENT YAW DIRECTION (_/57.2958 converts DEG to RADIANS)
xError2 = cos(correctedYaw2 / 57.2958)*(xPositionDesired2 - xPosition2) - sin(correctedYaw2 / 57.2958)*(yPositionDesired2 - yPosition2);
yError2 = sin(correctedYaw2 / 57.2958)*(xPositionDesired2 - xPosition2) + cos(correctedYaw2 / 57.2958)*(yPositionDesired2 - yPosition2);
#else
xError2 = xPositionDesired2 - xPosition2;
yError2 = yPositionDesired2 - yPosition2;
#endif
controllerSetXYError(&pidCtrl2, xError2, yError2);
</pre>
</code>
</blockquote>
This is no longer necessary on the Client because this is the exact same calculation ''CAREFREE'' mode performs on the Firmware. So this reduces the computation done on the Client in each Crazyflie Callback.
====Changing Yaw Mode in Firmware====
To change the Yaw Mode to ''CAREFREE'' mode we had to make the modification shown (code in ''Firmware > modules > interface > commander.h (line 36)''):
:'''ORIGINAL:'''
<blockquote>
<code>
<pre>
...
#ifdef PLATFORM_CF1
#define DEFUALT_YAW_MODE PLUSMODE
#else
#define DEFUALT_YAW_MODE XMODE
#endif
...
</pre>
</code>
</blockquote>
:'''MODIFIED:'''
<blockquote>
<code>
<pre>
...
#ifdef PLATFORM_CF1
#define DEFUALT_YAW_MODE PLUSMODE
#else
#define DEFUALT_YAW_MODE CAREFREE
#endif
...
</pre>
</code>
</blockquote>
::The code checks for which version Crazyflie you are using, either the original Crazyflie (<code>PLATFORM_CF1</code>), or the Crazyflie 2.0. We are using the Crazyflie 2.0 so we only care about the 2nd ''DEFAULT_YAW_MODE'', which we modified to ''CAREFREE'' mode as shown.
==New Firmware Parameter Groups==
Parameter groups are very similar to Log groups with a few key differences. An example of a Parameter group is shown (code in ''Firmware > modules > src > commander.c''):
:'''IMPORTANT:''' If you want to create new Parameter groups in a file, make sure you include <code>#include "param.h"</code> at the top of the file.
<blockquote>
<code>
<pre>
// Params for flight modes
PARAM_GROUP_START(flightmode)
PARAM_ADD(PARAM_UINT8, althold, &altHoldMode)
PARAM_ADD(PARAM_UINT8, yawMode, &yawMode)
PARAM_ADD(PARAM_UINT8, yawRst, &carefreeResetFront)
PARAM_ADD(PARAM_UINT8, stabModeRoll, &stabilizationModeRoll)
PARAM_ADD(PARAM_UINT8, stabModePitch, &stabilizationModePitch)
PARAM_ADD(PARAM_UINT8, stabModeYaw, &stabilizationModeYaw)
PARAM_GROUP_STOP(flightmode)
</pre>
</code>
</blockquote>
:So we create a parameter group called ''flightmode'' that contains the parameters listed. The difference between Log variables and Param variables is that for Param variables you need to specify the variable type (''PARAM_UINT8'' shown in the example).
Some User Friendly Param Types are shown below (you can find more complex Param types in ''Firmware > modules > interface > param.h'').
<blockquote>
<code>
<pre>
// User-friendly macros
#define PARAM_UINT8 (PARAM_1BYTE | PARAM_TYPE_INT | PARAM_UNSIGNED)
#define PARAM_INT8 (PARAM_1BYTE | PARAM_TYPE_INT | PARAM_SIGNED)
#define PARAM_UINT16 (PARAM_2BYTES | PARAM_TYPE_INT | PARAM_UNSIGNED)
#define PARAM_INT16 (PARAM_2BYTES | PARAM_TYPE_INT | PARAM_SIGNED)
#define PARAM_UINT32 (PARAM_4BYTES | PARAM_TYPE_INT | PARAM_UNSIGNED)
#define PARAM_INT32 (PARAM_4BYTES | PARAM_TYPE_INT | PARAM_SIGNED)
</pre>
</code>
</blockquote>
===Using Param Groups in Client===
This is not implemented yet (as of 7/21/16) but would be very nice to have. We could then tune Firmware PID constants without needing to flash the Firmware each time and much more.
If someone would like to attempt to create this you can see the Bitcraze Wiki page on the [https://wiki.bitcraze.io/doc:crazyflie:crtp:param Params Protocol] for help on how to implement this.
----
<center> '''Main Directory''' </center>
<center> [[Crazyflie Swarm|Crazyflie Swarm Home]] | [[PC Client Software]] | [[USB Radio]] | [[Firmware]] | [[FAQ]] </center>
<center> '''Modifications Directory''' </center>
<center> [[Controller]] | [[Logging]] | [[Keyboard Commands]] | [[USB Radio#Changing Radio Channel|Changing Radio Channel]] | [[Flight Modes]] | [[Callbacks]] | [[Adding a Crazyflie]] | [[Firmware]] </center>
4ab6ab8c47112c7ffc89f8b8387e87decb80d16e
248
247
2016-08-02T20:02:41Z
Jnoronha
3
/* Using Param Groups in Client */ linked param support future project idea
wikitext
text/x-wiki
Not much work has been done in the Firmware yet (as of 7/20/16). The few things we have been able to successfully modify are:
#Creating New Log Blocks
#Modifying the Default Yaw Mode
#Adding and Modifying Parameter Values
==New Firmware Log Blocks==
In the Crazyflie Firmware there is a generalized logging framework that allows us to make any group of variables into a log block. It makes things very easy to log. Here are a few examples:
:'''IMPORTANT:''' If you want to create new Log groups in a file, make sure you include <code>#include "log.h"</code> at the top of the file.
:Ex. 1. Magnometer Log Block (code found in ''Firmware > modules > src > stabilizer.c'')
<blockquote>
<code>
<pre>
LOG_GROUP_START(mag)
LOG_ADD(LOG_FLOAT, x, &mag.x)
LOG_ADD(LOG_FLOAT, y, &mag.y)
LOG_ADD(LOG_FLOAT, z, &mag.z)
LOG_GROUP_STOP(mag)
</pre>
</code>
</blockquote>
::So with this code we have created a log block called 'mag' and it contains the X, Y, and Z measurements from the magnetometer sensor.
:Ex. 2. Accelerometer Log Block (code found in ''Firmware > modules > src > stabilizer.c'')
<blockquote>
<code>
<pre>
LOG_GROUP_START(acc)
LOG_ADD(LOG_FLOAT, x, &acc.x)
LOG_ADD(LOG_FLOAT, y, &acc.y)
LOG_ADD(LOG_FLOAT, z, &acc.z)
LOG_ADD(LOG_FLOAT, zw, &accWZ)
LOG_ADD(LOG_FLOAT, mag2, &accMAG)
LOG_GROUP_STOP(acc)
</pre>
</code>
</blockquote>
::Just like in the magnetometer block, here we have created a log group called 'acc' and inside this group we are logging the variables for the accelerometer's X, Y, and Z values as well as 2 other gravity based variables used for thrust compensation.
===Using New Log Blocks in Swarm Client===
Now that we have these new log blocks in the Firmware, we can [[:Logging#New Client Log Blocks|use log blocks in the Client]]
==Modify the Default Yaw Mode==
There are 3 types of Yaw Modes available in the Firmware (as of 7/21/16), as shown (code in ''Firmware > modules > interface > commander.h'')
<blockquote>
<code>
<pre>
typedef enum
{
CAREFREE = 0, // Yaw is locked to world coordinates thus heading stays the same when yaw rotates
PLUSMODE = 1, // Plus-mode. Motor M1 is defined as front
XMODE = 2, // X-mode. M1 & M4 is defined as front
} YawModeType;
</pre>
</code>
</blockquote>
:'''Note:''' The default mode for the Crazyflie 2.0 is ''XMODE''. The ''PLUSMODE'' is default for the Crazyflie 1.0, but can still be used on the Crazyflie 2.0 if desired.
===Carefree Mode===
''CAREFREE'' mode is what our Crazyflie 2.0's are using, this mode applies a transformation to the Pitch and Roll setpoints depending on the angle of Yaw. We used to perform this calculation on the Client like this (code in ''eris_vrpn.cpp''):
<blockquote>
<code>
<pre>
#if USE_PR_YAW_CORRECT
//CORRECTS PITCH AND ROLL PID ERRORS TO ACCOUNT FOR QUADS CURRENT YAW DIRECTION (_/57.2958 converts DEG to RADIANS)
xError2 = cos(correctedYaw2 / 57.2958)*(xPositionDesired2 - xPosition2) - sin(correctedYaw2 / 57.2958)*(yPositionDesired2 - yPosition2);
yError2 = sin(correctedYaw2 / 57.2958)*(xPositionDesired2 - xPosition2) + cos(correctedYaw2 / 57.2958)*(yPositionDesired2 - yPosition2);
#else
xError2 = xPositionDesired2 - xPosition2;
yError2 = yPositionDesired2 - yPosition2;
#endif
controllerSetXYError(&pidCtrl2, xError2, yError2);
</pre>
</code>
</blockquote>
This is no longer necessary on the Client because this is the exact same calculation ''CAREFREE'' mode performs on the Firmware. So this reduces the computation done on the Client in each Crazyflie Callback.
====Changing Yaw Mode in Firmware====
To change the Yaw Mode to ''CAREFREE'' mode we had to make the modification shown (code in ''Firmware > modules > interface > commander.h (line 36)''):
:'''ORIGINAL:'''
<blockquote>
<code>
<pre>
...
#ifdef PLATFORM_CF1
#define DEFUALT_YAW_MODE PLUSMODE
#else
#define DEFUALT_YAW_MODE XMODE
#endif
...
</pre>
</code>
</blockquote>
:'''MODIFIED:'''
<blockquote>
<code>
<pre>
...
#ifdef PLATFORM_CF1
#define DEFUALT_YAW_MODE PLUSMODE
#else
#define DEFUALT_YAW_MODE CAREFREE
#endif
...
</pre>
</code>
</blockquote>
::The code checks for which version Crazyflie you are using, either the original Crazyflie (<code>PLATFORM_CF1</code>), or the Crazyflie 2.0. We are using the Crazyflie 2.0 so we only care about the 2nd ''DEFAULT_YAW_MODE'', which we modified to ''CAREFREE'' mode as shown.
==New Firmware Parameter Groups==
Parameter groups are very similar to Log groups with a few key differences. An example of a Parameter group is shown (code in ''Firmware > modules > src > commander.c''):
:'''IMPORTANT:''' If you want to create new Parameter groups in a file, make sure you include <code>#include "param.h"</code> at the top of the file.
<blockquote>
<code>
<pre>
// Params for flight modes
PARAM_GROUP_START(flightmode)
PARAM_ADD(PARAM_UINT8, althold, &altHoldMode)
PARAM_ADD(PARAM_UINT8, yawMode, &yawMode)
PARAM_ADD(PARAM_UINT8, yawRst, &carefreeResetFront)
PARAM_ADD(PARAM_UINT8, stabModeRoll, &stabilizationModeRoll)
PARAM_ADD(PARAM_UINT8, stabModePitch, &stabilizationModePitch)
PARAM_ADD(PARAM_UINT8, stabModeYaw, &stabilizationModeYaw)
PARAM_GROUP_STOP(flightmode)
</pre>
</code>
</blockquote>
:So we create a parameter group called ''flightmode'' that contains the parameters listed. The difference between Log variables and Param variables is that for Param variables you need to specify the variable type (''PARAM_UINT8'' shown in the example).
Some User Friendly Param Types are shown below (you can find more complex Param types in ''Firmware > modules > interface > param.h'').
<blockquote>
<code>
<pre>
// User-friendly macros
#define PARAM_UINT8 (PARAM_1BYTE | PARAM_TYPE_INT | PARAM_UNSIGNED)
#define PARAM_INT8 (PARAM_1BYTE | PARAM_TYPE_INT | PARAM_SIGNED)
#define PARAM_UINT16 (PARAM_2BYTES | PARAM_TYPE_INT | PARAM_UNSIGNED)
#define PARAM_INT16 (PARAM_2BYTES | PARAM_TYPE_INT | PARAM_SIGNED)
#define PARAM_UINT32 (PARAM_4BYTES | PARAM_TYPE_INT | PARAM_UNSIGNED)
#define PARAM_INT32 (PARAM_4BYTES | PARAM_TYPE_INT | PARAM_SIGNED)
</pre>
</code>
</blockquote>
===Using Param Groups in Client===
This is not implemented yet (as of 7/21/16) but would be very nice to have. We could then tune Firmware PID constants without needing to flash the Firmware each time and much more.
If someone would like to [[:Future Project Ideas#Adding Parameter Support to Swarm Client|attempt to create this]] you can see the Bitcraze Wiki page on the [https://wiki.bitcraze.io/doc:crazyflie:crtp:param Params Protocol] for help on how to implement this.
----
<center> '''Main Directory''' </center>
<center> [[Crazyflie Swarm|Crazyflie Swarm Home]] | [[PC Client Software]] | [[USB Radio]] | [[Firmware]] | [[FAQ]] </center>
<center> '''Modifications Directory''' </center>
<center> [[Controller]] | [[Logging]] | [[Keyboard Commands]] | [[USB Radio#Changing Radio Channel|Changing Radio Channel]] | [[Flight Modes]] | [[Callbacks]] | [[Adding a Crazyflie]] | [[Firmware]] </center>
6eca72d50daef7a8c92078de18f462499c8bbae5
Controller
0
5
229
133
2016-08-02T17:27:06Z
Jnoronha
3
/* State Estimator (Not Implemented Yet) */ added mention of a state feedback controller
wikitext
text/x-wiki
The Crazyflie platform is completely customizable when it comes to the control design. As long as the controller can be written in C or C++, we can implement it in the Platform. This applies to both the controllers run on the PC Client and the controllers run on the Firmware of the Crazyflie. Originally the only controllers in the Platform were Firmware PID's that controlled the angular position and rates of the Crazyflie for hand flight. The original controller layout can be seen here [[#Original PID Controllers (Angular Rotation)|Original PID's]].
Below you will find documentation on the different types of Controllers that have been applied to the platform, organized by their location in the Platform.
== Firmware ==
=== Original PID Controllers (Angular Rotation) ===
Directly on the Crazyflie Firmware there are 5 PID controllers as seen here:
[[Image:FirmwareOnlyPIDArchitecture.png|500px]]
The Pitch and Roll angular position PID's receive constant setpoints from some outside source (gamepad controller or automated controller). The outputs of those angular position controllers is then fed into the angular rate controllers as shown. This final output is then fed into the Motor Command block which converts the angular rate setpoints into motor commands.
----
===State Estimator (Not Implemented Yet)===
('''***NOT YET IMPLEMENTED***''')
Bitcraze is currently working on adding a state estimator and state-feedback controller onto the Firmware to handle control calculations instead of the PID.
The code is in place but the controller is not yet used as of '''7/13/16'''.
== PC Client ==
=== Client PID Controllers (Position and Yaw) ===
The first controller implemented on the Client were 4 PID controllers used to stabilize the Crazyflie's position in X, Y, and Z, and angular position in Yaw respectively. These PID's feed directly into the Firmware PID's as seen here:
[[Image:CompletePIDArchitectureFigure.png|500px]]
The controllers inside the red box are the original PID controllers located on the Firmware as shown above in the [[#Original PID Controllers (Angular Rotation)|Original PID's]].
====Initialize the PID's====
:1. To start we create a struct with all the necessary variables (code from ''pid.h''):
<blockquote>
<code>
<pre>
typedef struct
{
float desired; //< set point
float error; //< error
float prevError; //< previous error
float integ; //< integral
float deriv; //< derivative
float kp; //< proportional gain
float ki; //< integral gain
float kd; //< derivative gain
float outP; //< proportional output (debugging)
float outI; //< integral output (debugging)
float outD; //< derivative output (debugging)
float iLimit; //< integral limit
float iLimitLow; //< integral limit
float dt; //< delta-time dt
float angularLimit; //sets limit for how far Crazyflie can tip, to prevent flipping
float angularLimitLow; //^
float thrustLimit; //Sets upper limit for Thrust Output (60000?) **?
float thrustLimitLow; //Sets lower limit for thrust Output (10001)
} PidObject;
</pre>
</code>
</blockquote>
:2. To simplify scaling up the code to multiple Crazyflies, we will create a <code> ControllerObject </code> that contains multiple PID structs as shown (code in ''controller.h''):
<blockquote>
<code>
<pre>
typedef struct
{
PidObject pidRoll;
PidObject pidPitch;
PidObject pidYaw;
PidObject pidX;
PidObject pidY;
PidObject pidZ;
bool isInit;
} ControllerObject;
</pre>
</code>
</blockquote>
:3. Then we initialize the Objects to 0 at the start of each run (code in ''eris_vrpn.cpp''):
<blockquote>
<code>
<pre>
ControllerObject pidCtrl1 = { 0 }; // init all fields to zero
ControllerObject pidCtrl2 = { 0 }; // init all fields to zero
ControllerObject pidCtrl3 = { 0 }; // init all fields to zero
ControllerObject pidCtrl4 = { 0 }; // init all fields to zero
</pre>
</code>
</blockquote>
:4. Then populate the PidObjects with the desired parameters (code in ''pid.c''):
<blockquote>
<code>
<pre>
void pidInit(PidObject* pid, const float desired, const float kp,
const float ki, const float kd, const float dt)
{
pid->error = 0;
pid->prevError = 0;
pid->integ = 0;
pid->deriv = 0;
pid->desired = desired;
pid->kp = kp;
pid->ki = ki;
pid->kd = kd;
pid->iLimit = DEFAULT_PID_INTEGRATION_LIMIT;
pid->iLimitLow = -DEFAULT_PID_INTEGRATION_LIMIT;
pid->angularLimit = DEFAULT_PID_ANGLE_OUTPUT;
pid->angularLimitLow = -DEFAULT_PID_ANGLE_OUTPUT;
pid->thrustLimit = DEFAULT_PID_HIGH_THRUST_LIMIT;
pid->thrustLimitLow = DEFAULT_PID_LOW_THRUST_LIMIT;
pid->dt = dt;
}
</pre>
</code>
</blockquote>
Using the above function for each of the <code>PidObjects</code> inside of the <code>ControllerObject</code> below (code in ''controller.c''):
<blockquote>
<code>
<pre>
void controllerInit( ControllerObject * ctrl )
{
if(ctrl->isInit)
return;
pidInit(&ctrl->pidY, 0, PID_Y_KP, PID_Y_KI, PID_Y_KD, CAMERA_UPDATE_DT); //for Roll PID
pidInit(&ctrl->pidX, 0, PID_X_KP, PID_X_KI, PID_X_KD, CAMERA_UPDATE_DT); //for Pitch PID
pidInit(&ctrl->pidYaw, 0, PID_YAW_KP, PID_YAW_KI, PID_YAW_KD, CAMERA_UPDATE_DT);
pidInit(&ctrl->pidZ, 0, PID_Z_KP, PID_Z_KI, PID_Z_KD, CAMERA_UPDATE_DT);
pidSetIntegralLimit(&ctrl->pidY, PID_Y_INTEGRATION_LIMIT);
pidSetIntegralLimit(&ctrl->pidX, PID_X_INTEGRATION_LIMIT);
pidSetIntegralLimit(&ctrl->pidYaw, PID_YAW_INTEGRATION_LIMIT);
pidSetIntegralLimit(&ctrl->pidZ, PID_Z_INTEGRATION_LIMIT);
ctrl->isInit = true;
}
</pre>
</code>
</blockquote>
'''Note:''' If we have multiple Crazyflies we need a <code>ControllerObject</code> for each Crazyflie (code in ''eris_vrpn.cpp'')
<blockquote>
<code>
<pre>
controllerResetAllPID( &pidCtrl1 );
controllerInit( &pidCtrl1 );
#endif
#if NUM_QUADS >= 2
controllerResetAllPID( &pidCtrl2 );
controllerInit( &pidCtrl2 );
#endif
#if NUM_QUADS >=3
controllerResetAllPID( &pidCtrl3 );
controllerInit( &pidCtrl3 );
#endif
#if NUM_QUADS >=4
controllerResetAllPID( &pidCtrl4 );
controllerInit( &pidCtrl4 );
#endif
</pre>
</code>
</blockquote>
Now the initialization of the Controllers is complete.
====Calculating the PID's====
:1. Each loop we want to calculate the PID output (code in ''pid.c''):
<blockquote>
<code>
<pre>
float pidUpdateAngle(PidObject* pid, const float measured, const bool updateError) //**USED FOR ATTITUDE CONTROL
{
float output;
if(updateError)
{
pid->error = pid->desired - measured; //Calculates current error
}
pid->integ += pid->error * pid->dt; //Calculates integral term
if(pid->integ > pid->iLimit) //Checks that the integral term stays below the integral limit (anti-windup)
{
pid->integ = pid->iLimit;
}
else if(pid->integ < pid->iLimitLow)
{
pid->integ = pid->iLimitLow;
}
pid->deriv = (pid->error - pid->prevError) / pid->dt; //Calculates derivative term
pid->outP = pid->kp* pid->error;
pid->outI = pid->ki * pid->integ;
pid->outD = pid->kd * pid->deriv;
output = pid->outP + pid->outI + pid->outD; //Adds up all 3 calculated terms for output
if(output > pid->angularLimit) //Limits amount Crazyflie can tip
{
output = pid->angularLimit;
}
if(output < pid->angularLimitLow) //Limits amount Crazyflie can tip
{
output = pid->angularLimitLow;
}
pid->prevError = pid->error; //Stores the current error for next loop
return output;
}
</pre>
</code>
</blockquote>
::'''Note:''' There are 3 different versions of this Function (for Angle, Thrust, and Yaw) since each has different output limits.
:2. Using the function above, combine all PID calculations into one function (code in ''controller.c''):
<blockquote>
<code>
<pre>
void controllerCorrectAttitudePID(ControllerObject * ctrl,
float xPositionActual, float yPositionActual, float zPositionActual, float eulerYawActual, float xPositionDesired, float yPositionDesired,
float zPositionDesired, float eulerYawDesired, float* rollControlOutput, float* pitchControlOutput, float* yawControlOutput, float* thrustControlOutput)
{
pidSetDesired(&ctrl->pidX, xPositionDesired);
*pitchControlOutput = pidUpdateAngle(&ctrl->pidX, xPositionActual, false); //Originally true
pidSetDesired(&ctrl->pidY, yPositionDesired);
*rollControlOutput = pidUpdateAngle(&ctrl->pidY, yPositionActual, false); //Originally true
pidSetDesired(&ctrl->pidZ, zPositionDesired);
*thrustControlOutput = pidUpdateThrust(&ctrl->pidZ,zPositionActual, true);
float yawError;
pidSetDesired(&ctrl->pidYaw, eulerYawDesired);
yawError = eulerYawDesired - eulerYawActual;
if(yawError > 180.0) //Ensures Yaw error stays between -180 and 180 degrees
yawError -= 360.0;
else if(yawError < -180.0)
yawError += 360.0;
pidSetError(&ctrl->pidYaw, yawError);
*yawControlOutput = pidUpdateYaw(&ctrl->pidYaw, eulerYawActual, true); //originally false
}
</pre>
</code>
</blockquote>
:3. In each Callback, calculate the Controller outputs, assigned to pointer values <code>*rollControlOutput</code>, <code>*pitchControlOutput</code>, etc... (code in ''eris_vrpn.cpp''):
<blockquote>
<code>
<pre>
xError1 = xPositionDesired1 - xPosition1;
yError1 = yPositionDesired1 - yPosition1; //Calculates error externally
controllerSetXYError(&pidCtrl1, xError1, yError1);
controllerCorrectAttitudePID(&pidCtrl1, t.pos[0], t.pos[1], zPosition1, correctedYaw1,
xPositionDesired1, yPositionDesired1, zPositionDesired1,
yawDesired1, &rollControlOutput1, &pitchControlOutput1,
&yawControlOutput1, &thrustControlOutput1);
</pre>
</code>
</blockquote>
::'''Note 1:''' We calculate error externally for X and Y because certain swarm controllers need special setpoint modifiers (this way we can switch modes without effecting the default setpoint):
::'''Note 2:''' Swap out the Controller - all we need to do is create a similar function and replace ''controllerCorrectAttitudePID'' above
::'''Example:''' Follow Hand Mode Error (Crazyflie1 will have setpoint -0.5 m lower in X and +0.5 m higher in Y than your hand trackable):
<blockquote>
<code>
<pre>
...
xError1 = (xPositionHand - 0.5) - xPosition1;
yError1 = (yPositionHand + 0.5) - yPosition1;
controllerSetXYError(&pidCtrl1, xError1, yError1);
...
</pre>
</code>
</blockquote>
:4. Send Calculated Control Outputs to the Crazyflie via the Radio (code found in ''simple.cpp''):
<blockquote>
<code>
<pre>
RunCrazyflie(crRadio2, cflieCopter3, rollControlOutput3, pitchControlOutput3, yawControlOutput3, thrustControlOutput3);
</pre>
</code>
</blockquote>
::Where the ''RunCrazyflie'' function looks like this (code in ''simple.cpp''):
<blockquote>
<code>
<pre>
int RunCrazyflie(CCrazyRadio *crRadio, CCrazyflie *cflieCopter, float rollControl, float pitchControl, float yawControl, float thrustControl) {
//Timing Index Variables (**FOR TESTING ROUTINES**)
int i = 0;
while(cflieCopter->cycle()) {
//If Crazyflie is vertical kill motors, Crash Imminent
if(cflieCopter->roll() > 90){
cflieCopter->setThrust(10000);
}
else if(cflieCopter->roll() < -90){
cflieCopter->setThrust(10000);
}
else if(cflieCopter->pitch() > 90){
cflieCopter->setThrust(10000);
}
else if(cflieCopter->pitch() < -90){
cflieCopter->setThrust(10000);
}
//Otherwise Send Setpoints
else if(i < 1){ //i < 200000
cflieCopter->setThrust(thrustControl);
cflieCopter->setRoll(rollControl);
cflieCopter->setPitch(pitchControl);
cflieCopter->setYaw(-yawControl); //******SET TO NEGATIVE FOR CAMERA SYSTEM YAW BEING REVERSED!!!!****
i++;
}
else{
break;
}
}
return 0;
}
</pre>
</code>
</blockquote>
::'''IMPORTANT:''' This function contains the function <code>cflieCopter->cycle()</code> which is CRITICAL to maintaining communications with the Crazyflie. The ''cycle'' function initiates communications, sends setpoints, and must be called frequently otherwise the communications will timeout and the Crazyflie will stop as a precaution.
:5. Repeat steps 3 through 5 for each set of new location data...until Program END.
===Swapping Client Controller Type===
With the Swarm Platform we can plug any controller (that can be coded in C or C++) into the Client to control the Crazyflies.
In steps 1, 2, and 3 of the [[#Calculating the PID's|Calculating the PID's]] section, you can see the whole process of how we calculate the control output. To replace the PID with a different controller we can follow those steps but with our new controller. So as a general idea of the process we have:
('''Note:''' This depends heavily on how your controller works, this is generalized for a single input single output controller)
#Implement the New Controller Output Calculation in C as a function
#Create multiple instances of this controller calculation function (for each Degree of Freedom (DOF) you need to control) and combine them into a function to calculate all controllers with 1 function call ('''Note:''' This step is for ease of code use, NOT Required)
#In each Callback, call the function to Calculate the Controller output.
----
<center> '''Main Directory''' </center>
<center> [[Crazyflie Swarm|Crazyflie Swarm Home]] | [[PC Client Software]] | [[USB Radio]] | [[Firmware]] | [[FAQ]] </center>
<center> '''Modifications Directory''' </center>
<center> [[Controller]] | [[Logging]] | [[Keyboard Commands]] | [[USB Radio#Changing Radio Channel|Changing Radio Channel]] | [[Flight Modes]] | [[Callbacks]] | [[Adding a Crazyflie]] | [[Firmware]] </center>
cf76160409329e16e2c8389086c915e325131b3d
Logging
0
39
232
117
2016-08-02T18:55:19Z
Jnoronha
3
/* MATLAB Parser */ added data import and x and y positions
wikitext
text/x-wiki
The logging system is the most important analysis tool we have.
This allows us to export any variable data we want out to an external text file. This way we can use any data processor to parse the data. (Excel, MATLAB, R, etc.)
==Client-Side External Log Files==
We first need to initialize the log files and prepare them before each test.
:1. Create empty File Pointers (code in 'eris_vrpn.cpp')
<blockquote>
<code>
<pre>
FILE * outHand = NULL;
FILE * out1 = NULL;
FILE * out2 = NULL;
FILE * out3 = NULL;
FILE * out4 = NULL;
</pre>
</code>
</blockquote>
:2. Make sure Logging is Enabled (and Basic Logging if desired)
<blockquote>
<code>
<pre>
#define USE_VRPN 1
#define USE_KEYBOARD 1
#define USE_PRINTOUT 0
#define USE_LOGGING 1 <---//Enables Full Logging
#define USE_BASIC_LOGGING 1 <---//Only logs the necessities (FULL LOGGING MUST BE ENABLED FOR THIS TO WORK)
#define USE_PR_YAW_CORRECT 0
#define USE_HAND 1
</pre>
</code>
</blockquote>
:3. Create Log File Header (# = Log File Title, % = List of Variable Names, & = List of Variable Units)
::'''Note 1:''' This example is using BASIC_LOGGING 1,
::'''Note 2:''' Variables and units are separated by a double tab '\t\t' (Does not have to be '\t\t' any delimiter works)
<blockquote>
<code>
<pre>
const char * logHeaderHand = "#Hand Log File\n\
%Time\t\tPitch\t\tRoll\t\tYaw\t\tX\t\tY\t\tZ\t\tLoopTime\t\tLoopTimeDelta\n\
&sec\t\tdegrees\t\tdegrees\t\tdegrees\t\tmeters\t\tmeters\t\tmeters\t\tseconds\t\tseconds\n";
const char * logHeader1 = "#Crazyflie1 Log File\n\
%Time\t\tPitch\t\tRoll\t\tYaw\t\tX\t\tY\t\tZ\t\tCamYaw\t\tCorrectedYaw\t\tLoopTimeTotal\t\tLoopTimeTotalDelta\t\tLoopTime\t\tLoopTimeDelta\t\tvrpnPacketDelta\t\tvrpnPacketTime\t\tvrpnPacketBackup\t\tRadioRSSI\n\
&sec\t\tdegrees\t\tdegrees\t\tdegrees\t\tmeters\t\tmeters\t\tmeters\t\tdegrees\t\tdegrees\t\tseconds\t\tseconds\t\tseconds\t\tseconds\t\tseconds\t\tseconds\t\tpackets\t\tstrength\n";
const char * logHeader2 = "#Crazyflie2 Log File\n\
%Time\t\tPitch\t\tRoll\t\tYaw\t\tX\t\tY\t\tZ\t\tCamYaw\t\tCorrectedYaw\t\tLoopTimeTotal\t\tLoopTimeTotalDelta\t\tLoopTime\t\tLoopTimeDelta\t\tvrpnPacketDelta\t\tvrpnPacketTime\t\tvrpnPacketBackup\n\
&sec\t\tdegrees\t\tdegrees\t\tdegrees\t\tmeters\t\tmeters\t\tmeters\t\tdegrees\t\tdegrees\t\tseconds\t\tseconds\t\tseconds\t\tseconds\t\tseconds\t\tseconds\t\tpackets\n";
const char * logHeader3 = "#Crazyflie3 Log File\n\
%Time\t\tPitch\t\tRoll\t\tYaw\t\tX\t\tY\t\tZ\t\tCamYaw\t\tCorrectedYaw\t\tLoopTimeTotal\t\tLoopTimeTotalDelta\t\tLoopTime\t\tLoopTimeDelta\t\tvrpnPacketDelta\t\tvrpnPacketTime\t\tvrpnPacketBackup\n\
&sec\t\tdegrees\t\tdegrees\t\tdegrees\t\tmeters\t\tmeters\t\tmeters\t\tdegrees\t\tdegrees\t\tseconds\t\tseconds\t\tseconds\t\tseconds\t\tseconds\t\tseconds\t\tpackets\n";
const char * logHeader4 = "#Crazyflie4 Log File\n\
%Time\t\tPitch\t\tRoll\t\tYaw\t\tX\t\tY\t\tZ\t\tCamYaw\t\tCorrectedYaw\t\tLoopTimeTotal\t\tLoopTimeTotalDelta\t\tLoopTime\t\tLoopTimeDelta\t\tvrpnPacketDelta\t\tvrpnPacketTime\t\tvrpnPacketBackup\n\
&sec\t\tdegrees\t\tdegrees\t\tdegrees\t\tmeters\t\tmeters\t\tmeters\t\tdegrees\t\tdegrees\t\tseconds\t\tseconds\t\tseconds\t\tseconds\t\tseconds\t\tseconds\t\tpackets\n";
</pre>
</code>
</blockquote>
:4. Open External .txt file and Print Header into file
<blockquote>
<code>
<pre>
#if USE_HAND
outHand = fopen("hand.txt", "w"); //Opens text file with write permission
if(outHand == NULL)
{
printf("Could not open hand.log: errno %d\n", errno);
exit(-1);
}
fprintf(outHand, "%s\n", logHeaderHand); //Prints log header into corresponding file
#endif
if(cflieCopter1) //Checks to see if cflieCopter pointer has been initialized before opening file
{
out1 = fopen("cflie1.txt", "w");
if(out1 == NULL)
{
printf("Could not open cflie1.log: errno %d\n", errno);
exit(-1);
}
fprintf(out1, "%s\n", logHeader1);
}
if(cflieCopter2)
{
out2 = fopen("cflie2.txt", "w");
if(out2 == NULL)
{
printf("Could not open cflie2.log:errno %d\n", errno);
exit(-1);
}
fprintf(out2, "%s\n", logHeader2);
}
if(cflieCopter3)
{
out3 = fopen("cflie3.txt", "w");
if(out3 == NULL)
{
printf("Could not open cflie3.log:errno %d\n", errno);
exit(-1);
}
fprintf(out3, "%s\n", logHeader3);
}
if(cflieCopter4)
{
out4 = fopen("cflie4.txt", "w");
if(out4 == NULL)
{
printf("Could not open cflie4.log:errno %d\n", errno);
exit(-1);
}
fprintf(out4, "%s\n", logHeader4);
}
</pre>
</code>
</blockquote>
:5. Init has Completed (Start Program Loop) Prints Variable values to file...
::'''Note 1:''' This code is run at the end of the Callback for each Crazyflie initialized (Executes once per new data packet)
::'''Note 2:''' This example is using BASIC_LOGGING, and is only showing Crazyflie1's code.
<blockquote>
<code>
<pre>
fprintf(out1, "%.6f\t\t", cflieCopter1->currentTime() - initTime1 );
fprintf(out1, "%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.6f\t\t%.6f\t\t%.6f\t\t%.6f\t\t%.6f\t\t%.6f\t\t%d\t\t%d",
cflieCopter1->roll(),
cflieCopter1->pitch(),
quadYaw1,
t.pos[0],
t.pos[1],
-t.pos[2],
camYawDeg1,
correctedYaw1,
loopTimeTotal,
loopTimeTotalDelta,
loopTime1,
loopTime1Delta,
vrpnPacketDelta1,
vrpnPacketTime1,
vrpnPacketBackup1,
cflieCopter1->radioRSSI());
fprintf(out1, "\n");
</pre>
</code>
</blockquote>
:6. Close External .txt files before ending program
<blockquote>
<code>
<pre>
#if USE_LOGGING
#if USE_HAND
fclose(outHand);
#endif
#if NUM_QUADS >= 1
fclose(out1);
#endif
#if NUM_QUADS >= 2
fclose(out2);
#endif
#if NUM_QUADS >= 3
fclose(out3);
#endif
#if NUM_QUADS >= 4
fclose(out4);
#endif
#endif
</pre>
</code>
</blockquote>
==MATLAB Parser==
'''(**TODO**)'''
We use a Matlab script to parse the log files.
===Multi-Logfile Parser===
The primary way we use to visualize the log files is via a very simple and messy MATLAB script. It consists of a bunch of sub-routines that were all thrown together into a single .m file.
====Import Log Data====
<blockquote>
<code>
<pre>
%% Crazyflie Logging Parser
[handLog, delimHand] = importdata('hand.txt','\t'); %Imports data from all 5 log files from the Swarm Client
[cflie1Log, delim1] = importdata('cflie1.txt','\t');
[cflie2Log, delim2] = importdata('cflie2.txt','\t');
[cflie3Log, delim3] = importdata('cflie3.txt','\t');
[cflie4Log, delim4] = importdata('cflie4.txt','\t');
%
handTime = handLog.data(:,1);
handRoll = handLog.data(:,3);
handPitch = handLog.data(:,5);
handYaw = handLog.data(:,7);
handX = handLog.data(:,9); %Assigns Hand Data to user-friendly variable names
handY = handLog.data(:,11);
handZ = handLog.data(:,13);
handLoopTime = handLog.data(:,15);
handLoopTimeDelta = handLog.data(:,17);
%
cflie1Time = cflie1Log.data(:,1);
cflie1Roll = cflie1Log.data(:,3);
cflie1Pitch = cflie1Log.data(:,5); %Assigns Crazyflie1 Data to user-friendly variable names
cflie1Yaw = cflie1Log.data(:,7);
cflie1X = cflie1Log.data(:,9);
cflie1Y = cflie1Log.data(:,11);
cflie1Z = cflie1Log.data(:,13);
cflie1CamYaw = cflie1Log.data(:,15);
cflie1CorrectedYaw = cflie1Log.data(:,17);
cflie1LoopTimeTotal = cflie1Log.data(:,19);
cflie1LoopTimeTotalDelta = cflie1Log.data(:,21);
cflie1LoopTime = cflie1Log.data(:,23);
cflie1LoopTimeDelta = cflie1Log.data(:,25);
cflie1VrpnPacketDelta = cflie1Log.data(:,27);
cflie1VrpnPacketTime = cflie1Log.data(:,29);
cflie1VrpnPacketBackup = cflie1Log.data(:,31);
% cflie1XSetpoint = cflie1Log.data(:,33);
% cflie1YSetpoint = cflie1Log.data(:,35);
% cflie1ZSetpoint = cflie1Log.data(:,37);
% cflie1YawSetpoint = cflie1Log.data(:,39);
% cflie1PitchDesired = cflie1Log.data(:,41);
% cflie1RollDesired = cflie1Log.data(:,43);
% cflie1YawDesired = cflie1Log.data(:,45);
% cflie1ThrustDesired = cflie1Log.data(:,47);
% cflie1RadioRSSI = cflie1Log.data(:,49);
% cflie1CamYawRad = cflie1Log.data(:,51);
% cflie1CamPitchRad = cflie1Log.data(:,53);
% cflie1CamRollRad = cflie1Log.data(:,55);
% cflie1Motor1 = cflie1Log.data(:,57);
% cflie1Motor2 = cflie1Log.data(:,59);
% cflie1Motor3 = cflie1Log.data(:,61);
% cflie1Motor4 = cflie1Log.data(:,63);
% cflie1RollRate = cflie1Log.data(:,65);
% cflie1PitchRate = cflie1Log.data(:,67);
% cflie1YawRate = cflie1Log.data(:,69);
...
...
...
(same for Crazyflie 2, 3, and 4..)
...
...
</pre>
</code>
</blockquote>
::'''Note:''' This list needs to match the log file length that the Swarm Client creates (comment out as needed)
====Plotting X and Y Position of Crazyflies====
<blockquote>
<code>
<pre>
%% Plot X Using ImportData
figure(8) %Plotting X-Positions
hold off
plot(cflie1Time,cflie1X, '-b')
hold on
% plot(cflie1Time,cflie1XSetpoint, '-.b')
%
plot(cflie2Time,cflie2X, '-g')
% plot(cflie2Time,cflie2XSetpoint, '-.g')
%
plot(cflie3Time,cflie3X, '-k')
% plot(cflie3Time,cflie3XSetpoint, '-.k')
%
plot(cflie4Time,cflie4X, '-y')
%
plot(handTime, handX, '-r')
% plot(cflie4Time,cflie4XSetpoint, '-.y')
title 'Crazyflie X-Positions'
legend('Crazyflie 1','Crazyflie 2','Crazyflie3', 'Crazyflie4', 'Hand')
xlabel 'Time (seconds)'
ylabel 'X-Position (m)'
grid on
% legend('Crazyflie 1','Setpoint', 'Crazyflie 2','Setpoint', 'Crazyflie3','Setpoint', 'Crazyflie4','Setpoint')
%
%
figure(9) %Plotting Y-Positions
hold off
plot(cflie1Time,cflie1Y, '-b')
hold on
% plot(cflie1Time,cflie1YSetpoint, '-.b')
%
plot(cflie2Time,cflie2Y, '-g')
% plot(cflie2Time,cflie2YSetpoint, '-.g')
%
plot(cflie3Time,cflie3Y, '-k')
% plot(cflie3Time,cflie3YSetpoint, '-.k')
%
plot(cflie4Time,cflie4Y, '-y')
% plot(cflie3Time,cflie3YSetpoint, '-.y')
%
plot(handTime, handY, '-r')
title 'Crazyflie Y-Positions'
legend('Crazyflie 1','Crazyflie 2','Crazyflie3', 'Crazyflie4', 'Hand')
% legend('Crazyflie 1', 'Setpoint','Crazyflie 2', 'Setpoint','Crazyflie3','Setpoint', 'Crazyflie4','Setpoint')
xlabel 'Time (seconds)'
ylabel 'Y-Position (m)'
grid on
</pre>
</code>
</blockquote>
===[http://wikis.ece.iastate.edu/robotic-agriculture-data-acquisition/index.php/Data_Analysis_Tool Universal Lab Parser (Alternative)]===
Alternatively, the lab has a unified logging format that can be read by a universal log parser. More information about this parsing method [http://wikis.ece.iastate.edu/robotic-agriculture-data-acquisition/index.php/Data_Analysis_Tool can be found here]
The Swarm Platform log files are compatible with this format and can be used just as any other lab log files. The problem is that this parser can '''only view a single text file at a time'''. This makes comparisons and plotting across all Crazyflies in the swarm very very difficult.
==New Client Log Blocks==
In the Swarm Client there is a sub-system designed for creating and maintaining Log Blocks. Once you have [[:Firmware#Log Blocks|created a new log block in the Firmware]] that you want to utilize we can do the following:
:1. Create an Enable function for the New Log Block (code in ''CCrazyflie.cpp'')
<blockquote>
<code>
<pre>
void CCrazyflie::enableMagnetometerLogging() {
m_tocLogs->registerLoggingBlock("magnetometer", 1000);
m_tocLogs->startLogging("mag.x", "magnetometer");
m_tocLogs->startLogging("mag.y", "magnetometer");
m_tocLogs->startLogging("mag.z", "magnetometer");
}
</pre>
</code>
</blockquote>
::This will then register a log block called ''magnetometer'' on the Client, which will be updated every 1000 μs. It will then update the values listed in the block (X, Y, Z of the magnetometer).
::'''Note 1:''' The ''"mag.x"'' term must match the name defined in the Firmware log block (see [[:Firmware#Log Blocks|firmware example 1]])
::'''Note 2:''' The 2nd input to the ''startLogging'' function needs to match the name of the Client Log block we registered (in this case ''"magnetometer"'')
:2. Add the ''enableLogBlock'' function we just made to the list of Log blocks we want at startup (code in ''CCrazyflie.cpp''):
<blockquote>
<code>
<pre>
bool CCrazyflie::startLogging() {
// Register the desired sensor readings
this->enableStabilizerLogging();
// this->enableGyroscopeLogging();
// this->enableAccelerometerLogging();
this->enableBatteryLogging();
this->enableMagnetometerLogging(); <-----//This is the one we just made
// this->enableAltimeterLogging();
// this->enablePIDOutputLogging();
// this->enableRadioRSSILogging();
// this->enableMotorLogging();
return true;
}
</pre>
</code>
</blockquote>
::This ''startLogging'' function runs during Crazyflie startup and will start all the log blocks listed. As you can see we have some log blocks commented out currently so that we do NOT start those blocks.
:3. Create Functions to Read the variable values during runtime (code in ''CCrazyflie.cpp''):
<blockquote>
<code>
<pre>
float CCrazyflie::magX() {
return this->sensorDoubleValue("mag.x");
}
float CCrazyflie::magY() {
return this->sensorDoubleValue("mag.y");
}
float CCrazyflie::magZ() {
return this->sensorDoubleValue("mag.z");
}
</pre>
</code>
</blockquote>
::So now we can use these sensor values, from the Firmware, in the Client code with <code>magX1 = cflieCopter1->magX()</code>. This will store the sensor value in the Client-side variable ''magX1''.
:4. (OPTIONAL) We can also create a function to stop logging an individual log block in the Client (code in ''CCrazyflie.cpp'')
<blockquote>
<code>
<pre>
void CCrazyflie::disableMagnetometerLogging() {
m_tocLogs->unregisterLoggingBlock("magnetometer");
}
</pre>
</code>
</blockquote>
::This is straightforward, it just tells the client to stop logging this block.
:5. (OPTIONAL) And we can stop ALL log blocks in the client as well (code in ''CCrazyflie.cpp''):
<blockquote>
<code>
<pre>
bool CCrazyflie::stopLogging() {
this->disableStabilizerLogging();
this->disableGyroscopeLogging();
this->disableAccelerometerLogging();
this->disableBatteryLogging();
// this->disableMagnetometerLogging();
// this->disableAltimeterLogging();
// this->disablePIDOutputLogging();
this->disableRadioRSSILogging();
this->disableMotorLogging();
return true;
}
</pre>
</code>
</blockquote>
::This will disable ALL the logging blocks included in the list.
----
<center> '''Main Directory''' </center>
<center> [[Crazyflie Swarm|Crazyflie Swarm Home]] | [[PC Client Software]] | [[USB Radio]] | [[Firmware]] | [[FAQ]] </center>
<center> '''Modifications Directory''' </center>
<center> [[Controller]] | [[Logging]] | [[Keyboard Commands]] | [[USB Radio#Changing Radio Channel|Changing Radio Channel]] | [[Flight Modes]] | [[Callbacks]] | [[Adding a Crazyflie]] | [[Firmware]] </center>
720bf5dc37b42ee104353cd69a0df6294642ad6d
233
232
2016-08-02T19:00:24Z
Jnoronha
3
moved the matlab section to the bottom
wikitext
text/x-wiki
The logging system is the most important analysis tool we have.
This allows us to export any variable data we want out to an external text file. This way we can use any data processor to parse the data. (Excel, MATLAB, R, etc.)
==Client-Side External Log Files==
We first need to initialize the log files and prepare them before each test.
:1. Create empty File Pointers (code in 'eris_vrpn.cpp')
<blockquote>
<code>
<pre>
FILE * outHand = NULL;
FILE * out1 = NULL;
FILE * out2 = NULL;
FILE * out3 = NULL;
FILE * out4 = NULL;
</pre>
</code>
</blockquote>
:2. Make sure Logging is Enabled (and Basic Logging if desired)
<blockquote>
<code>
<pre>
#define USE_VRPN 1
#define USE_KEYBOARD 1
#define USE_PRINTOUT 0
#define USE_LOGGING 1 <---//Enables Full Logging
#define USE_BASIC_LOGGING 1 <---//Only logs the necessities (FULL LOGGING MUST BE ENABLED FOR THIS TO WORK)
#define USE_PR_YAW_CORRECT 0
#define USE_HAND 1
</pre>
</code>
</blockquote>
:3. Create Log File Header (# = Log File Title, % = List of Variable Names, & = List of Variable Units)
::'''Note 1:''' This example is using BASIC_LOGGING 1,
::'''Note 2:''' Variables and units are separated by a double tab '\t\t' (Does not have to be '\t\t' any delimiter works)
<blockquote>
<code>
<pre>
const char * logHeaderHand = "#Hand Log File\n\
%Time\t\tPitch\t\tRoll\t\tYaw\t\tX\t\tY\t\tZ\t\tLoopTime\t\tLoopTimeDelta\n\
&sec\t\tdegrees\t\tdegrees\t\tdegrees\t\tmeters\t\tmeters\t\tmeters\t\tseconds\t\tseconds\n";
const char * logHeader1 = "#Crazyflie1 Log File\n\
%Time\t\tPitch\t\tRoll\t\tYaw\t\tX\t\tY\t\tZ\t\tCamYaw\t\tCorrectedYaw\t\tLoopTimeTotal\t\tLoopTimeTotalDelta\t\tLoopTime\t\tLoopTimeDelta\t\tvrpnPacketDelta\t\tvrpnPacketTime\t\tvrpnPacketBackup\t\tRadioRSSI\n\
&sec\t\tdegrees\t\tdegrees\t\tdegrees\t\tmeters\t\tmeters\t\tmeters\t\tdegrees\t\tdegrees\t\tseconds\t\tseconds\t\tseconds\t\tseconds\t\tseconds\t\tseconds\t\tpackets\t\tstrength\n";
const char * logHeader2 = "#Crazyflie2 Log File\n\
%Time\t\tPitch\t\tRoll\t\tYaw\t\tX\t\tY\t\tZ\t\tCamYaw\t\tCorrectedYaw\t\tLoopTimeTotal\t\tLoopTimeTotalDelta\t\tLoopTime\t\tLoopTimeDelta\t\tvrpnPacketDelta\t\tvrpnPacketTime\t\tvrpnPacketBackup\n\
&sec\t\tdegrees\t\tdegrees\t\tdegrees\t\tmeters\t\tmeters\t\tmeters\t\tdegrees\t\tdegrees\t\tseconds\t\tseconds\t\tseconds\t\tseconds\t\tseconds\t\tseconds\t\tpackets\n";
const char * logHeader3 = "#Crazyflie3 Log File\n\
%Time\t\tPitch\t\tRoll\t\tYaw\t\tX\t\tY\t\tZ\t\tCamYaw\t\tCorrectedYaw\t\tLoopTimeTotal\t\tLoopTimeTotalDelta\t\tLoopTime\t\tLoopTimeDelta\t\tvrpnPacketDelta\t\tvrpnPacketTime\t\tvrpnPacketBackup\n\
&sec\t\tdegrees\t\tdegrees\t\tdegrees\t\tmeters\t\tmeters\t\tmeters\t\tdegrees\t\tdegrees\t\tseconds\t\tseconds\t\tseconds\t\tseconds\t\tseconds\t\tseconds\t\tpackets\n";
const char * logHeader4 = "#Crazyflie4 Log File\n\
%Time\t\tPitch\t\tRoll\t\tYaw\t\tX\t\tY\t\tZ\t\tCamYaw\t\tCorrectedYaw\t\tLoopTimeTotal\t\tLoopTimeTotalDelta\t\tLoopTime\t\tLoopTimeDelta\t\tvrpnPacketDelta\t\tvrpnPacketTime\t\tvrpnPacketBackup\n\
&sec\t\tdegrees\t\tdegrees\t\tdegrees\t\tmeters\t\tmeters\t\tmeters\t\tdegrees\t\tdegrees\t\tseconds\t\tseconds\t\tseconds\t\tseconds\t\tseconds\t\tseconds\t\tpackets\n";
</pre>
</code>
</blockquote>
:4. Open External .txt file and Print Header into file
<blockquote>
<code>
<pre>
#if USE_HAND
outHand = fopen("hand.txt", "w"); //Opens text file with write permission
if(outHand == NULL)
{
printf("Could not open hand.log: errno %d\n", errno);
exit(-1);
}
fprintf(outHand, "%s\n", logHeaderHand); //Prints log header into corresponding file
#endif
if(cflieCopter1) //Checks to see if cflieCopter pointer has been initialized before opening file
{
out1 = fopen("cflie1.txt", "w");
if(out1 == NULL)
{
printf("Could not open cflie1.log: errno %d\n", errno);
exit(-1);
}
fprintf(out1, "%s\n", logHeader1);
}
if(cflieCopter2)
{
out2 = fopen("cflie2.txt", "w");
if(out2 == NULL)
{
printf("Could not open cflie2.log:errno %d\n", errno);
exit(-1);
}
fprintf(out2, "%s\n", logHeader2);
}
if(cflieCopter3)
{
out3 = fopen("cflie3.txt", "w");
if(out3 == NULL)
{
printf("Could not open cflie3.log:errno %d\n", errno);
exit(-1);
}
fprintf(out3, "%s\n", logHeader3);
}
if(cflieCopter4)
{
out4 = fopen("cflie4.txt", "w");
if(out4 == NULL)
{
printf("Could not open cflie4.log:errno %d\n", errno);
exit(-1);
}
fprintf(out4, "%s\n", logHeader4);
}
</pre>
</code>
</blockquote>
:5. Init has Completed (Start Program Loop) Prints Variable values to file...
::'''Note 1:''' This code is run at the end of the Callback for each Crazyflie initialized (Executes once per new data packet)
::'''Note 2:''' This example is using BASIC_LOGGING, and is only showing Crazyflie1's code.
<blockquote>
<code>
<pre>
fprintf(out1, "%.6f\t\t", cflieCopter1->currentTime() - initTime1 );
fprintf(out1, "%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.6f\t\t%.6f\t\t%.6f\t\t%.6f\t\t%.6f\t\t%.6f\t\t%d\t\t%d",
cflieCopter1->roll(),
cflieCopter1->pitch(),
quadYaw1,
t.pos[0],
t.pos[1],
-t.pos[2],
camYawDeg1,
correctedYaw1,
loopTimeTotal,
loopTimeTotalDelta,
loopTime1,
loopTime1Delta,
vrpnPacketDelta1,
vrpnPacketTime1,
vrpnPacketBackup1,
cflieCopter1->radioRSSI());
fprintf(out1, "\n");
</pre>
</code>
</blockquote>
:6. Close External .txt files before ending program
<blockquote>
<code>
<pre>
#if USE_LOGGING
#if USE_HAND
fclose(outHand);
#endif
#if NUM_QUADS >= 1
fclose(out1);
#endif
#if NUM_QUADS >= 2
fclose(out2);
#endif
#if NUM_QUADS >= 3
fclose(out3);
#endif
#if NUM_QUADS >= 4
fclose(out4);
#endif
#endif
</pre>
</code>
</blockquote>
===[http://wikis.ece.iastate.edu/robotic-agriculture-data-acquisition/index.php/Data_Analysis_Tool Universal Lab Parser (Alternative)]===
Alternatively, the lab has a unified logging format that can be read by a universal log parser. More information about this parsing method [http://wikis.ece.iastate.edu/robotic-agriculture-data-acquisition/index.php/Data_Analysis_Tool can be found here]
The Swarm Platform log files are compatible with this format and can be used just as any other lab log files. The problem is that this parser can '''only view a single text file at a time'''. This makes comparisons and plotting across all Crazyflies in the swarm very very difficult.
==New Client Log Blocks==
In the Swarm Client there is a sub-system designed for creating and maintaining Log Blocks. Once you have [[:Firmware#Log Blocks|created a new log block in the Firmware]] that you want to utilize we can do the following:
:1. Create an Enable function for the New Log Block (code in ''CCrazyflie.cpp'')
<blockquote>
<code>
<pre>
void CCrazyflie::enableMagnetometerLogging() {
m_tocLogs->registerLoggingBlock("magnetometer", 1000);
m_tocLogs->startLogging("mag.x", "magnetometer");
m_tocLogs->startLogging("mag.y", "magnetometer");
m_tocLogs->startLogging("mag.z", "magnetometer");
}
</pre>
</code>
</blockquote>
::This will then register a log block called ''magnetometer'' on the Client, which will be updated every 1000 μs. It will then update the values listed in the block (X, Y, Z of the magnetometer).
::'''Note 1:''' The ''"mag.x"'' term must match the name defined in the Firmware log block (see [[:Firmware#Log Blocks|firmware example 1]])
::'''Note 2:''' The 2nd input to the ''startLogging'' function needs to match the name of the Client Log block we registered (in this case ''"magnetometer"'')
:2. Add the ''enableLogBlock'' function we just made to the list of Log blocks we want at startup (code in ''CCrazyflie.cpp''):
<blockquote>
<code>
<pre>
bool CCrazyflie::startLogging() {
// Register the desired sensor readings
this->enableStabilizerLogging();
// this->enableGyroscopeLogging();
// this->enableAccelerometerLogging();
this->enableBatteryLogging();
this->enableMagnetometerLogging(); <-----//This is the one we just made
// this->enableAltimeterLogging();
// this->enablePIDOutputLogging();
// this->enableRadioRSSILogging();
// this->enableMotorLogging();
return true;
}
</pre>
</code>
</blockquote>
::This ''startLogging'' function runs during Crazyflie startup and will start all the log blocks listed. As you can see we have some log blocks commented out currently so that we do NOT start those blocks.
:3. Create Functions to Read the variable values during runtime (code in ''CCrazyflie.cpp''):
<blockquote>
<code>
<pre>
float CCrazyflie::magX() {
return this->sensorDoubleValue("mag.x");
}
float CCrazyflie::magY() {
return this->sensorDoubleValue("mag.y");
}
float CCrazyflie::magZ() {
return this->sensorDoubleValue("mag.z");
}
</pre>
</code>
</blockquote>
::So now we can use these sensor values, from the Firmware, in the Client code with <code>magX1 = cflieCopter1->magX()</code>. This will store the sensor value in the Client-side variable ''magX1''.
:4. (OPTIONAL) We can also create a function to stop logging an individual log block in the Client (code in ''CCrazyflie.cpp'')
<blockquote>
<code>
<pre>
void CCrazyflie::disableMagnetometerLogging() {
m_tocLogs->unregisterLoggingBlock("magnetometer");
}
</pre>
</code>
</blockquote>
::This is straightforward, it just tells the client to stop logging this block.
:5. (OPTIONAL) And we can stop ALL log blocks in the client as well (code in ''CCrazyflie.cpp''):
<blockquote>
<code>
<pre>
bool CCrazyflie::stopLogging() {
this->disableStabilizerLogging();
this->disableGyroscopeLogging();
this->disableAccelerometerLogging();
this->disableBatteryLogging();
// this->disableMagnetometerLogging();
// this->disableAltimeterLogging();
// this->disablePIDOutputLogging();
this->disableRadioRSSILogging();
this->disableMotorLogging();
return true;
}
</pre>
</code>
</blockquote>
::This will disable ALL the logging blocks included in the list.
==MATLAB Parser==
'''(**TODO**)'''
We use a Matlab script to parse the log files.
===Multi-Logfile Parser===
The primary way we use to visualize the log files is via a very simple and messy MATLAB script. It consists of a bunch of sub-routines that were all thrown together into a single .m file.
====Import Log Data====
<blockquote>
<code>
<pre>
%% Crazyflie Logging Parser
[handLog, delimHand] = importdata('hand.txt','\t'); %Imports data from all 5 log files from the Swarm Client
[cflie1Log, delim1] = importdata('cflie1.txt','\t');
[cflie2Log, delim2] = importdata('cflie2.txt','\t');
[cflie3Log, delim3] = importdata('cflie3.txt','\t');
[cflie4Log, delim4] = importdata('cflie4.txt','\t');
%
handTime = handLog.data(:,1);
handRoll = handLog.data(:,3);
handPitch = handLog.data(:,5);
handYaw = handLog.data(:,7);
handX = handLog.data(:,9); %Assigns Hand Data to user-friendly variable names
handY = handLog.data(:,11);
handZ = handLog.data(:,13);
handLoopTime = handLog.data(:,15);
handLoopTimeDelta = handLog.data(:,17);
%
cflie1Time = cflie1Log.data(:,1);
cflie1Roll = cflie1Log.data(:,3);
cflie1Pitch = cflie1Log.data(:,5); %Assigns Crazyflie1 Data to user-friendly variable names
cflie1Yaw = cflie1Log.data(:,7);
cflie1X = cflie1Log.data(:,9);
cflie1Y = cflie1Log.data(:,11);
cflie1Z = cflie1Log.data(:,13);
cflie1CamYaw = cflie1Log.data(:,15);
cflie1CorrectedYaw = cflie1Log.data(:,17);
cflie1LoopTimeTotal = cflie1Log.data(:,19);
cflie1LoopTimeTotalDelta = cflie1Log.data(:,21);
cflie1LoopTime = cflie1Log.data(:,23);
cflie1LoopTimeDelta = cflie1Log.data(:,25);
cflie1VrpnPacketDelta = cflie1Log.data(:,27);
cflie1VrpnPacketTime = cflie1Log.data(:,29);
cflie1VrpnPacketBackup = cflie1Log.data(:,31);
% cflie1XSetpoint = cflie1Log.data(:,33);
% cflie1YSetpoint = cflie1Log.data(:,35);
% cflie1ZSetpoint = cflie1Log.data(:,37);
% cflie1YawSetpoint = cflie1Log.data(:,39);
% cflie1PitchDesired = cflie1Log.data(:,41);
% cflie1RollDesired = cflie1Log.data(:,43);
% cflie1YawDesired = cflie1Log.data(:,45);
% cflie1ThrustDesired = cflie1Log.data(:,47);
% cflie1RadioRSSI = cflie1Log.data(:,49);
% cflie1CamYawRad = cflie1Log.data(:,51);
% cflie1CamPitchRad = cflie1Log.data(:,53);
% cflie1CamRollRad = cflie1Log.data(:,55);
% cflie1Motor1 = cflie1Log.data(:,57);
% cflie1Motor2 = cflie1Log.data(:,59);
% cflie1Motor3 = cflie1Log.data(:,61);
% cflie1Motor4 = cflie1Log.data(:,63);
% cflie1RollRate = cflie1Log.data(:,65);
% cflie1PitchRate = cflie1Log.data(:,67);
% cflie1YawRate = cflie1Log.data(:,69);
...
...
...
(same for Crazyflie 2, 3, and 4..)
...
...
</pre>
</code>
</blockquote>
::'''Note:''' This list needs to match the log file length that the Swarm Client creates (comment out as needed)
====Plotting X and Y Position of Crazyflies====
<blockquote>
<code>
<pre>
%% Plot X Using ImportData
figure(8) %Plotting X-Positions
hold off
plot(cflie1Time,cflie1X, '-b')
hold on
% plot(cflie1Time,cflie1XSetpoint, '-.b')
%
plot(cflie2Time,cflie2X, '-g')
% plot(cflie2Time,cflie2XSetpoint, '-.g')
%
plot(cflie3Time,cflie3X, '-k')
% plot(cflie3Time,cflie3XSetpoint, '-.k')
%
plot(cflie4Time,cflie4X, '-y')
%
plot(handTime, handX, '-r')
% plot(cflie4Time,cflie4XSetpoint, '-.y')
title 'Crazyflie X-Positions'
legend('Crazyflie 1','Crazyflie 2','Crazyflie3', 'Crazyflie4', 'Hand')
xlabel 'Time (seconds)'
ylabel 'X-Position (m)'
grid on
% legend('Crazyflie 1','Setpoint', 'Crazyflie 2','Setpoint', 'Crazyflie3','Setpoint', 'Crazyflie4','Setpoint')
%
%
figure(9) %Plotting Y-Positions
hold off
plot(cflie1Time,cflie1Y, '-b')
hold on
% plot(cflie1Time,cflie1YSetpoint, '-.b')
%
plot(cflie2Time,cflie2Y, '-g')
% plot(cflie2Time,cflie2YSetpoint, '-.g')
%
plot(cflie3Time,cflie3Y, '-k')
% plot(cflie3Time,cflie3YSetpoint, '-.k')
%
plot(cflie4Time,cflie4Y, '-y')
% plot(cflie3Time,cflie3YSetpoint, '-.y')
%
plot(handTime, handY, '-r')
title 'Crazyflie Y-Positions'
legend('Crazyflie 1','Crazyflie 2','Crazyflie3', 'Crazyflie4', 'Hand')
% legend('Crazyflie 1', 'Setpoint','Crazyflie 2', 'Setpoint','Crazyflie3','Setpoint', 'Crazyflie4','Setpoint')
xlabel 'Time (seconds)'
ylabel 'Y-Position (m)'
grid on
</pre>
</code>
</blockquote>
----
<center> '''Main Directory''' </center>
<center> [[Crazyflie Swarm|Crazyflie Swarm Home]] | [[PC Client Software]] | [[USB Radio]] | [[Firmware]] | [[FAQ]] </center>
<center> '''Modifications Directory''' </center>
<center> [[Controller]] | [[Logging]] | [[Keyboard Commands]] | [[USB Radio#Changing Radio Channel|Changing Radio Channel]] | [[Flight Modes]] | [[Callbacks]] | [[Adding a Crazyflie]] | [[Firmware]] </center>
09f13122bea10e3a9d412fa98ba333701d2e6708
234
233
2016-08-02T19:01:47Z
Jnoronha
3
forgot to move the universal parser also
wikitext
text/x-wiki
The logging system is the most important analysis tool we have.
This allows us to export any variable data we want out to an external text file. This way we can use any data processor to parse the data. (Excel, MATLAB, R, etc.)
==Client-Side External Log Files==
We first need to initialize the log files and prepare them before each test.
:1. Create empty File Pointers (code in 'eris_vrpn.cpp')
<blockquote>
<code>
<pre>
FILE * outHand = NULL;
FILE * out1 = NULL;
FILE * out2 = NULL;
FILE * out3 = NULL;
FILE * out4 = NULL;
</pre>
</code>
</blockquote>
:2. Make sure Logging is Enabled (and Basic Logging if desired)
<blockquote>
<code>
<pre>
#define USE_VRPN 1
#define USE_KEYBOARD 1
#define USE_PRINTOUT 0
#define USE_LOGGING 1 <---//Enables Full Logging
#define USE_BASIC_LOGGING 1 <---//Only logs the necessities (FULL LOGGING MUST BE ENABLED FOR THIS TO WORK)
#define USE_PR_YAW_CORRECT 0
#define USE_HAND 1
</pre>
</code>
</blockquote>
:3. Create Log File Header (# = Log File Title, % = List of Variable Names, & = List of Variable Units)
::'''Note 1:''' This example is using BASIC_LOGGING 1,
::'''Note 2:''' Variables and units are separated by a double tab '\t\t' (Does not have to be '\t\t' any delimiter works)
<blockquote>
<code>
<pre>
const char * logHeaderHand = "#Hand Log File\n\
%Time\t\tPitch\t\tRoll\t\tYaw\t\tX\t\tY\t\tZ\t\tLoopTime\t\tLoopTimeDelta\n\
&sec\t\tdegrees\t\tdegrees\t\tdegrees\t\tmeters\t\tmeters\t\tmeters\t\tseconds\t\tseconds\n";
const char * logHeader1 = "#Crazyflie1 Log File\n\
%Time\t\tPitch\t\tRoll\t\tYaw\t\tX\t\tY\t\tZ\t\tCamYaw\t\tCorrectedYaw\t\tLoopTimeTotal\t\tLoopTimeTotalDelta\t\tLoopTime\t\tLoopTimeDelta\t\tvrpnPacketDelta\t\tvrpnPacketTime\t\tvrpnPacketBackup\t\tRadioRSSI\n\
&sec\t\tdegrees\t\tdegrees\t\tdegrees\t\tmeters\t\tmeters\t\tmeters\t\tdegrees\t\tdegrees\t\tseconds\t\tseconds\t\tseconds\t\tseconds\t\tseconds\t\tseconds\t\tpackets\t\tstrength\n";
const char * logHeader2 = "#Crazyflie2 Log File\n\
%Time\t\tPitch\t\tRoll\t\tYaw\t\tX\t\tY\t\tZ\t\tCamYaw\t\tCorrectedYaw\t\tLoopTimeTotal\t\tLoopTimeTotalDelta\t\tLoopTime\t\tLoopTimeDelta\t\tvrpnPacketDelta\t\tvrpnPacketTime\t\tvrpnPacketBackup\n\
&sec\t\tdegrees\t\tdegrees\t\tdegrees\t\tmeters\t\tmeters\t\tmeters\t\tdegrees\t\tdegrees\t\tseconds\t\tseconds\t\tseconds\t\tseconds\t\tseconds\t\tseconds\t\tpackets\n";
const char * logHeader3 = "#Crazyflie3 Log File\n\
%Time\t\tPitch\t\tRoll\t\tYaw\t\tX\t\tY\t\tZ\t\tCamYaw\t\tCorrectedYaw\t\tLoopTimeTotal\t\tLoopTimeTotalDelta\t\tLoopTime\t\tLoopTimeDelta\t\tvrpnPacketDelta\t\tvrpnPacketTime\t\tvrpnPacketBackup\n\
&sec\t\tdegrees\t\tdegrees\t\tdegrees\t\tmeters\t\tmeters\t\tmeters\t\tdegrees\t\tdegrees\t\tseconds\t\tseconds\t\tseconds\t\tseconds\t\tseconds\t\tseconds\t\tpackets\n";
const char * logHeader4 = "#Crazyflie4 Log File\n\
%Time\t\tPitch\t\tRoll\t\tYaw\t\tX\t\tY\t\tZ\t\tCamYaw\t\tCorrectedYaw\t\tLoopTimeTotal\t\tLoopTimeTotalDelta\t\tLoopTime\t\tLoopTimeDelta\t\tvrpnPacketDelta\t\tvrpnPacketTime\t\tvrpnPacketBackup\n\
&sec\t\tdegrees\t\tdegrees\t\tdegrees\t\tmeters\t\tmeters\t\tmeters\t\tdegrees\t\tdegrees\t\tseconds\t\tseconds\t\tseconds\t\tseconds\t\tseconds\t\tseconds\t\tpackets\n";
</pre>
</code>
</blockquote>
:4. Open External .txt file and Print Header into file
<blockquote>
<code>
<pre>
#if USE_HAND
outHand = fopen("hand.txt", "w"); //Opens text file with write permission
if(outHand == NULL)
{
printf("Could not open hand.log: errno %d\n", errno);
exit(-1);
}
fprintf(outHand, "%s\n", logHeaderHand); //Prints log header into corresponding file
#endif
if(cflieCopter1) //Checks to see if cflieCopter pointer has been initialized before opening file
{
out1 = fopen("cflie1.txt", "w");
if(out1 == NULL)
{
printf("Could not open cflie1.log: errno %d\n", errno);
exit(-1);
}
fprintf(out1, "%s\n", logHeader1);
}
if(cflieCopter2)
{
out2 = fopen("cflie2.txt", "w");
if(out2 == NULL)
{
printf("Could not open cflie2.log:errno %d\n", errno);
exit(-1);
}
fprintf(out2, "%s\n", logHeader2);
}
if(cflieCopter3)
{
out3 = fopen("cflie3.txt", "w");
if(out3 == NULL)
{
printf("Could not open cflie3.log:errno %d\n", errno);
exit(-1);
}
fprintf(out3, "%s\n", logHeader3);
}
if(cflieCopter4)
{
out4 = fopen("cflie4.txt", "w");
if(out4 == NULL)
{
printf("Could not open cflie4.log:errno %d\n", errno);
exit(-1);
}
fprintf(out4, "%s\n", logHeader4);
}
</pre>
</code>
</blockquote>
:5. Init has Completed (Start Program Loop) Prints Variable values to file...
::'''Note 1:''' This code is run at the end of the Callback for each Crazyflie initialized (Executes once per new data packet)
::'''Note 2:''' This example is using BASIC_LOGGING, and is only showing Crazyflie1's code.
<blockquote>
<code>
<pre>
fprintf(out1, "%.6f\t\t", cflieCopter1->currentTime() - initTime1 );
fprintf(out1, "%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.6f\t\t%.6f\t\t%.6f\t\t%.6f\t\t%.6f\t\t%.6f\t\t%d\t\t%d",
cflieCopter1->roll(),
cflieCopter1->pitch(),
quadYaw1,
t.pos[0],
t.pos[1],
-t.pos[2],
camYawDeg1,
correctedYaw1,
loopTimeTotal,
loopTimeTotalDelta,
loopTime1,
loopTime1Delta,
vrpnPacketDelta1,
vrpnPacketTime1,
vrpnPacketBackup1,
cflieCopter1->radioRSSI());
fprintf(out1, "\n");
</pre>
</code>
</blockquote>
:6. Close External .txt files before ending program
<blockquote>
<code>
<pre>
#if USE_LOGGING
#if USE_HAND
fclose(outHand);
#endif
#if NUM_QUADS >= 1
fclose(out1);
#endif
#if NUM_QUADS >= 2
fclose(out2);
#endif
#if NUM_QUADS >= 3
fclose(out3);
#endif
#if NUM_QUADS >= 4
fclose(out4);
#endif
#endif
</pre>
</code>
</blockquote>
==New Client Log Blocks==
In the Swarm Client there is a sub-system designed for creating and maintaining Log Blocks. Once you have [[:Firmware#Log Blocks|created a new log block in the Firmware]] that you want to utilize we can do the following:
:1. Create an Enable function for the New Log Block (code in ''CCrazyflie.cpp'')
<blockquote>
<code>
<pre>
void CCrazyflie::enableMagnetometerLogging() {
m_tocLogs->registerLoggingBlock("magnetometer", 1000);
m_tocLogs->startLogging("mag.x", "magnetometer");
m_tocLogs->startLogging("mag.y", "magnetometer");
m_tocLogs->startLogging("mag.z", "magnetometer");
}
</pre>
</code>
</blockquote>
::This will then register a log block called ''magnetometer'' on the Client, which will be updated every 1000 μs. It will then update the values listed in the block (X, Y, Z of the magnetometer).
::'''Note 1:''' The ''"mag.x"'' term must match the name defined in the Firmware log block (see [[:Firmware#Log Blocks|firmware example 1]])
::'''Note 2:''' The 2nd input to the ''startLogging'' function needs to match the name of the Client Log block we registered (in this case ''"magnetometer"'')
:2. Add the ''enableLogBlock'' function we just made to the list of Log blocks we want at startup (code in ''CCrazyflie.cpp''):
<blockquote>
<code>
<pre>
bool CCrazyflie::startLogging() {
// Register the desired sensor readings
this->enableStabilizerLogging();
// this->enableGyroscopeLogging();
// this->enableAccelerometerLogging();
this->enableBatteryLogging();
this->enableMagnetometerLogging(); <-----//This is the one we just made
// this->enableAltimeterLogging();
// this->enablePIDOutputLogging();
// this->enableRadioRSSILogging();
// this->enableMotorLogging();
return true;
}
</pre>
</code>
</blockquote>
::This ''startLogging'' function runs during Crazyflie startup and will start all the log blocks listed. As you can see we have some log blocks commented out currently so that we do NOT start those blocks.
:3. Create Functions to Read the variable values during runtime (code in ''CCrazyflie.cpp''):
<blockquote>
<code>
<pre>
float CCrazyflie::magX() {
return this->sensorDoubleValue("mag.x");
}
float CCrazyflie::magY() {
return this->sensorDoubleValue("mag.y");
}
float CCrazyflie::magZ() {
return this->sensorDoubleValue("mag.z");
}
</pre>
</code>
</blockquote>
::So now we can use these sensor values, from the Firmware, in the Client code with <code>magX1 = cflieCopter1->magX()</code>. This will store the sensor value in the Client-side variable ''magX1''.
:4. (OPTIONAL) We can also create a function to stop logging an individual log block in the Client (code in ''CCrazyflie.cpp'')
<blockquote>
<code>
<pre>
void CCrazyflie::disableMagnetometerLogging() {
m_tocLogs->unregisterLoggingBlock("magnetometer");
}
</pre>
</code>
</blockquote>
::This is straightforward, it just tells the client to stop logging this block.
:5. (OPTIONAL) And we can stop ALL log blocks in the client as well (code in ''CCrazyflie.cpp''):
<blockquote>
<code>
<pre>
bool CCrazyflie::stopLogging() {
this->disableStabilizerLogging();
this->disableGyroscopeLogging();
this->disableAccelerometerLogging();
this->disableBatteryLogging();
// this->disableMagnetometerLogging();
// this->disableAltimeterLogging();
// this->disablePIDOutputLogging();
this->disableRadioRSSILogging();
this->disableMotorLogging();
return true;
}
</pre>
</code>
</blockquote>
::This will disable ALL the logging blocks included in the list.
==MATLAB Parser==
'''(**TODO**)'''
We use a Matlab script to parse the log files.
===Multi-Logfile Parser===
The primary way we use to visualize the log files is via a very simple and messy MATLAB script. It consists of a bunch of sub-routines that were all thrown together into a single .m file.
====Import Log Data====
<blockquote>
<code>
<pre>
%% Crazyflie Logging Parser
[handLog, delimHand] = importdata('hand.txt','\t'); %Imports data from all 5 log files from the Swarm Client
[cflie1Log, delim1] = importdata('cflie1.txt','\t');
[cflie2Log, delim2] = importdata('cflie2.txt','\t');
[cflie3Log, delim3] = importdata('cflie3.txt','\t');
[cflie4Log, delim4] = importdata('cflie4.txt','\t');
%
handTime = handLog.data(:,1);
handRoll = handLog.data(:,3);
handPitch = handLog.data(:,5);
handYaw = handLog.data(:,7);
handX = handLog.data(:,9); %Assigns Hand Data to user-friendly variable names
handY = handLog.data(:,11);
handZ = handLog.data(:,13);
handLoopTime = handLog.data(:,15);
handLoopTimeDelta = handLog.data(:,17);
%
cflie1Time = cflie1Log.data(:,1);
cflie1Roll = cflie1Log.data(:,3);
cflie1Pitch = cflie1Log.data(:,5); %Assigns Crazyflie1 Data to user-friendly variable names
cflie1Yaw = cflie1Log.data(:,7);
cflie1X = cflie1Log.data(:,9);
cflie1Y = cflie1Log.data(:,11);
cflie1Z = cflie1Log.data(:,13);
cflie1CamYaw = cflie1Log.data(:,15);
cflie1CorrectedYaw = cflie1Log.data(:,17);
cflie1LoopTimeTotal = cflie1Log.data(:,19);
cflie1LoopTimeTotalDelta = cflie1Log.data(:,21);
cflie1LoopTime = cflie1Log.data(:,23);
cflie1LoopTimeDelta = cflie1Log.data(:,25);
cflie1VrpnPacketDelta = cflie1Log.data(:,27);
cflie1VrpnPacketTime = cflie1Log.data(:,29);
cflie1VrpnPacketBackup = cflie1Log.data(:,31);
% cflie1XSetpoint = cflie1Log.data(:,33);
% cflie1YSetpoint = cflie1Log.data(:,35);
% cflie1ZSetpoint = cflie1Log.data(:,37);
% cflie1YawSetpoint = cflie1Log.data(:,39);
% cflie1PitchDesired = cflie1Log.data(:,41);
% cflie1RollDesired = cflie1Log.data(:,43);
% cflie1YawDesired = cflie1Log.data(:,45);
% cflie1ThrustDesired = cflie1Log.data(:,47);
% cflie1RadioRSSI = cflie1Log.data(:,49);
% cflie1CamYawRad = cflie1Log.data(:,51);
% cflie1CamPitchRad = cflie1Log.data(:,53);
% cflie1CamRollRad = cflie1Log.data(:,55);
% cflie1Motor1 = cflie1Log.data(:,57);
% cflie1Motor2 = cflie1Log.data(:,59);
% cflie1Motor3 = cflie1Log.data(:,61);
% cflie1Motor4 = cflie1Log.data(:,63);
% cflie1RollRate = cflie1Log.data(:,65);
% cflie1PitchRate = cflie1Log.data(:,67);
% cflie1YawRate = cflie1Log.data(:,69);
...
...
...
(same for Crazyflie 2, 3, and 4..)
...
...
</pre>
</code>
</blockquote>
::'''Note:''' This list needs to match the log file length that the Swarm Client creates (comment out as needed)
====Plotting X and Y Position of Crazyflies====
<blockquote>
<code>
<pre>
%% Plot X Using ImportData
figure(8) %Plotting X-Positions
hold off
plot(cflie1Time,cflie1X, '-b')
hold on
% plot(cflie1Time,cflie1XSetpoint, '-.b')
%
plot(cflie2Time,cflie2X, '-g')
% plot(cflie2Time,cflie2XSetpoint, '-.g')
%
plot(cflie3Time,cflie3X, '-k')
% plot(cflie3Time,cflie3XSetpoint, '-.k')
%
plot(cflie4Time,cflie4X, '-y')
%
plot(handTime, handX, '-r')
% plot(cflie4Time,cflie4XSetpoint, '-.y')
title 'Crazyflie X-Positions'
legend('Crazyflie 1','Crazyflie 2','Crazyflie3', 'Crazyflie4', 'Hand')
xlabel 'Time (seconds)'
ylabel 'X-Position (m)'
grid on
% legend('Crazyflie 1','Setpoint', 'Crazyflie 2','Setpoint', 'Crazyflie3','Setpoint', 'Crazyflie4','Setpoint')
%
%
figure(9) %Plotting Y-Positions
hold off
plot(cflie1Time,cflie1Y, '-b')
hold on
% plot(cflie1Time,cflie1YSetpoint, '-.b')
%
plot(cflie2Time,cflie2Y, '-g')
% plot(cflie2Time,cflie2YSetpoint, '-.g')
%
plot(cflie3Time,cflie3Y, '-k')
% plot(cflie3Time,cflie3YSetpoint, '-.k')
%
plot(cflie4Time,cflie4Y, '-y')
% plot(cflie3Time,cflie3YSetpoint, '-.y')
%
plot(handTime, handY, '-r')
title 'Crazyflie Y-Positions'
legend('Crazyflie 1','Crazyflie 2','Crazyflie3', 'Crazyflie4', 'Hand')
% legend('Crazyflie 1', 'Setpoint','Crazyflie 2', 'Setpoint','Crazyflie3','Setpoint', 'Crazyflie4','Setpoint')
xlabel 'Time (seconds)'
ylabel 'Y-Position (m)'
grid on
</pre>
</code>
</blockquote>
===[http://wikis.ece.iastate.edu/robotic-agriculture-data-acquisition/index.php/Data_Analysis_Tool Universal Lab Parser (Alternative)]===
Alternatively, the lab has a unified logging format that can be read by a universal log parser. More information about this parsing method [http://wikis.ece.iastate.edu/robotic-agriculture-data-acquisition/index.php/Data_Analysis_Tool can be found here]
The Swarm Platform log files are compatible with this format and can be used just as any other lab log files. The problem is that this parser can '''only view a single text file at a time'''. This makes comparisons and plotting across all Crazyflies in the swarm very very difficult.
----
<center> '''Main Directory''' </center>
<center> [[Crazyflie Swarm|Crazyflie Swarm Home]] | [[PC Client Software]] | [[USB Radio]] | [[Firmware]] | [[FAQ]] </center>
<center> '''Modifications Directory''' </center>
<center> [[Controller]] | [[Logging]] | [[Keyboard Commands]] | [[USB Radio#Changing Radio Channel|Changing Radio Channel]] | [[Flight Modes]] | [[Callbacks]] | [[Adding a Crazyflie]] | [[Firmware]] </center>
4da73c93ed2dd4ef436688937ad8869626b34e4f
240
234
2016-08-02T19:47:14Z
Jnoronha
3
/* MATLAB Parser */ added figures and finished usable sections
wikitext
text/x-wiki
The logging system is the most important analysis tool we have.
This allows us to export any variable data we want out to an external text file. This way we can use any data processor to parse the data. (Excel, MATLAB, R, etc.)
==Client-Side External Log Files==
We first need to initialize the log files and prepare them before each test.
:1. Create empty File Pointers (code in 'eris_vrpn.cpp')
<blockquote>
<code>
<pre>
FILE * outHand = NULL;
FILE * out1 = NULL;
FILE * out2 = NULL;
FILE * out3 = NULL;
FILE * out4 = NULL;
</pre>
</code>
</blockquote>
:2. Make sure Logging is Enabled (and Basic Logging if desired)
<blockquote>
<code>
<pre>
#define USE_VRPN 1
#define USE_KEYBOARD 1
#define USE_PRINTOUT 0
#define USE_LOGGING 1 <---//Enables Full Logging
#define USE_BASIC_LOGGING 1 <---//Only logs the necessities (FULL LOGGING MUST BE ENABLED FOR THIS TO WORK)
#define USE_PR_YAW_CORRECT 0
#define USE_HAND 1
</pre>
</code>
</blockquote>
:3. Create Log File Header (# = Log File Title, % = List of Variable Names, & = List of Variable Units)
::'''Note 1:''' This example is using BASIC_LOGGING 1,
::'''Note 2:''' Variables and units are separated by a double tab '\t\t' (Does not have to be '\t\t' any delimiter works)
<blockquote>
<code>
<pre>
const char * logHeaderHand = "#Hand Log File\n\
%Time\t\tPitch\t\tRoll\t\tYaw\t\tX\t\tY\t\tZ\t\tLoopTime\t\tLoopTimeDelta\n\
&sec\t\tdegrees\t\tdegrees\t\tdegrees\t\tmeters\t\tmeters\t\tmeters\t\tseconds\t\tseconds\n";
const char * logHeader1 = "#Crazyflie1 Log File\n\
%Time\t\tPitch\t\tRoll\t\tYaw\t\tX\t\tY\t\tZ\t\tCamYaw\t\tCorrectedYaw\t\tLoopTimeTotal\t\tLoopTimeTotalDelta\t\tLoopTime\t\tLoopTimeDelta\t\tvrpnPacketDelta\t\tvrpnPacketTime\t\tvrpnPacketBackup\t\tRadioRSSI\n\
&sec\t\tdegrees\t\tdegrees\t\tdegrees\t\tmeters\t\tmeters\t\tmeters\t\tdegrees\t\tdegrees\t\tseconds\t\tseconds\t\tseconds\t\tseconds\t\tseconds\t\tseconds\t\tpackets\t\tstrength\n";
const char * logHeader2 = "#Crazyflie2 Log File\n\
%Time\t\tPitch\t\tRoll\t\tYaw\t\tX\t\tY\t\tZ\t\tCamYaw\t\tCorrectedYaw\t\tLoopTimeTotal\t\tLoopTimeTotalDelta\t\tLoopTime\t\tLoopTimeDelta\t\tvrpnPacketDelta\t\tvrpnPacketTime\t\tvrpnPacketBackup\n\
&sec\t\tdegrees\t\tdegrees\t\tdegrees\t\tmeters\t\tmeters\t\tmeters\t\tdegrees\t\tdegrees\t\tseconds\t\tseconds\t\tseconds\t\tseconds\t\tseconds\t\tseconds\t\tpackets\n";
const char * logHeader3 = "#Crazyflie3 Log File\n\
%Time\t\tPitch\t\tRoll\t\tYaw\t\tX\t\tY\t\tZ\t\tCamYaw\t\tCorrectedYaw\t\tLoopTimeTotal\t\tLoopTimeTotalDelta\t\tLoopTime\t\tLoopTimeDelta\t\tvrpnPacketDelta\t\tvrpnPacketTime\t\tvrpnPacketBackup\n\
&sec\t\tdegrees\t\tdegrees\t\tdegrees\t\tmeters\t\tmeters\t\tmeters\t\tdegrees\t\tdegrees\t\tseconds\t\tseconds\t\tseconds\t\tseconds\t\tseconds\t\tseconds\t\tpackets\n";
const char * logHeader4 = "#Crazyflie4 Log File\n\
%Time\t\tPitch\t\tRoll\t\tYaw\t\tX\t\tY\t\tZ\t\tCamYaw\t\tCorrectedYaw\t\tLoopTimeTotal\t\tLoopTimeTotalDelta\t\tLoopTime\t\tLoopTimeDelta\t\tvrpnPacketDelta\t\tvrpnPacketTime\t\tvrpnPacketBackup\n\
&sec\t\tdegrees\t\tdegrees\t\tdegrees\t\tmeters\t\tmeters\t\tmeters\t\tdegrees\t\tdegrees\t\tseconds\t\tseconds\t\tseconds\t\tseconds\t\tseconds\t\tseconds\t\tpackets\n";
</pre>
</code>
</blockquote>
:4. Open External .txt file and Print Header into file
<blockquote>
<code>
<pre>
#if USE_HAND
outHand = fopen("hand.txt", "w"); //Opens text file with write permission
if(outHand == NULL)
{
printf("Could not open hand.log: errno %d\n", errno);
exit(-1);
}
fprintf(outHand, "%s\n", logHeaderHand); //Prints log header into corresponding file
#endif
if(cflieCopter1) //Checks to see if cflieCopter pointer has been initialized before opening file
{
out1 = fopen("cflie1.txt", "w");
if(out1 == NULL)
{
printf("Could not open cflie1.log: errno %d\n", errno);
exit(-1);
}
fprintf(out1, "%s\n", logHeader1);
}
if(cflieCopter2)
{
out2 = fopen("cflie2.txt", "w");
if(out2 == NULL)
{
printf("Could not open cflie2.log:errno %d\n", errno);
exit(-1);
}
fprintf(out2, "%s\n", logHeader2);
}
if(cflieCopter3)
{
out3 = fopen("cflie3.txt", "w");
if(out3 == NULL)
{
printf("Could not open cflie3.log:errno %d\n", errno);
exit(-1);
}
fprintf(out3, "%s\n", logHeader3);
}
if(cflieCopter4)
{
out4 = fopen("cflie4.txt", "w");
if(out4 == NULL)
{
printf("Could not open cflie4.log:errno %d\n", errno);
exit(-1);
}
fprintf(out4, "%s\n", logHeader4);
}
</pre>
</code>
</blockquote>
:5. Init has Completed (Start Program Loop) Prints Variable values to file...
::'''Note 1:''' This code is run at the end of the Callback for each Crazyflie initialized (Executes once per new data packet)
::'''Note 2:''' This example is using BASIC_LOGGING, and is only showing Crazyflie1's code.
<blockquote>
<code>
<pre>
fprintf(out1, "%.6f\t\t", cflieCopter1->currentTime() - initTime1 );
fprintf(out1, "%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.6f\t\t%.6f\t\t%.6f\t\t%.6f\t\t%.6f\t\t%.6f\t\t%d\t\t%d",
cflieCopter1->roll(),
cflieCopter1->pitch(),
quadYaw1,
t.pos[0],
t.pos[1],
-t.pos[2],
camYawDeg1,
correctedYaw1,
loopTimeTotal,
loopTimeTotalDelta,
loopTime1,
loopTime1Delta,
vrpnPacketDelta1,
vrpnPacketTime1,
vrpnPacketBackup1,
cflieCopter1->radioRSSI());
fprintf(out1, "\n");
</pre>
</code>
</blockquote>
:6. Close External .txt files before ending program
<blockquote>
<code>
<pre>
#if USE_LOGGING
#if USE_HAND
fclose(outHand);
#endif
#if NUM_QUADS >= 1
fclose(out1);
#endif
#if NUM_QUADS >= 2
fclose(out2);
#endif
#if NUM_QUADS >= 3
fclose(out3);
#endif
#if NUM_QUADS >= 4
fclose(out4);
#endif
#endif
</pre>
</code>
</blockquote>
==New Client Log Blocks==
In the Swarm Client there is a sub-system designed for creating and maintaining Log Blocks. Once you have [[:Firmware#Log Blocks|created a new log block in the Firmware]] that you want to utilize we can do the following:
:1. Create an Enable function for the New Log Block (code in ''CCrazyflie.cpp'')
<blockquote>
<code>
<pre>
void CCrazyflie::enableMagnetometerLogging() {
m_tocLogs->registerLoggingBlock("magnetometer", 1000);
m_tocLogs->startLogging("mag.x", "magnetometer");
m_tocLogs->startLogging("mag.y", "magnetometer");
m_tocLogs->startLogging("mag.z", "magnetometer");
}
</pre>
</code>
</blockquote>
::This will then register a log block called ''magnetometer'' on the Client, which will be updated every 1000 μs. It will then update the values listed in the block (X, Y, Z of the magnetometer).
::'''Note 1:''' The ''"mag.x"'' term must match the name defined in the Firmware log block (see [[:Firmware#Log Blocks|firmware example 1]])
::'''Note 2:''' The 2nd input to the ''startLogging'' function needs to match the name of the Client Log block we registered (in this case ''"magnetometer"'')
:2. Add the ''enableLogBlock'' function we just made to the list of Log blocks we want at startup (code in ''CCrazyflie.cpp''):
<blockquote>
<code>
<pre>
bool CCrazyflie::startLogging() {
// Register the desired sensor readings
this->enableStabilizerLogging();
// this->enableGyroscopeLogging();
// this->enableAccelerometerLogging();
this->enableBatteryLogging();
this->enableMagnetometerLogging(); <-----//This is the one we just made
// this->enableAltimeterLogging();
// this->enablePIDOutputLogging();
// this->enableRadioRSSILogging();
// this->enableMotorLogging();
return true;
}
</pre>
</code>
</blockquote>
::This ''startLogging'' function runs during Crazyflie startup and will start all the log blocks listed. As you can see we have some log blocks commented out currently so that we do NOT start those blocks.
:3. Create Functions to Read the variable values during runtime (code in ''CCrazyflie.cpp''):
<blockquote>
<code>
<pre>
float CCrazyflie::magX() {
return this->sensorDoubleValue("mag.x");
}
float CCrazyflie::magY() {
return this->sensorDoubleValue("mag.y");
}
float CCrazyflie::magZ() {
return this->sensorDoubleValue("mag.z");
}
</pre>
</code>
</blockquote>
::So now we can use these sensor values, from the Firmware, in the Client code with <code>magX1 = cflieCopter1->magX()</code>. This will store the sensor value in the Client-side variable ''magX1''.
:4. (OPTIONAL) We can also create a function to stop logging an individual log block in the Client (code in ''CCrazyflie.cpp'')
<blockquote>
<code>
<pre>
void CCrazyflie::disableMagnetometerLogging() {
m_tocLogs->unregisterLoggingBlock("magnetometer");
}
</pre>
</code>
</blockquote>
::This is straightforward, it just tells the client to stop logging this block.
:5. (OPTIONAL) And we can stop ALL log blocks in the client as well (code in ''CCrazyflie.cpp''):
<blockquote>
<code>
<pre>
bool CCrazyflie::stopLogging() {
this->disableStabilizerLogging();
this->disableGyroscopeLogging();
this->disableAccelerometerLogging();
this->disableBatteryLogging();
// this->disableMagnetometerLogging();
// this->disableAltimeterLogging();
// this->disablePIDOutputLogging();
this->disableRadioRSSILogging();
this->disableMotorLogging();
return true;
}
</pre>
</code>
</blockquote>
::This will disable ALL the logging blocks included in the list.
==MATLAB Parser==
'''(**TODO**)'''
We use a Matlab script to parse the log files.
===Multi-Logfile Parser===
The primary way we use to visualize the log files is via a very simple and messy MATLAB script. It consists of a bunch of sub-routines that were all thrown together into a single .m file.
====Import Log Data====
<blockquote>
<code>
<pre>
%% Crazyflie Logging Parser
[handLog, delimHand] = importdata('hand.txt','\t'); %Imports data from all 5 log files from the Swarm Client
[cflie1Log, delim1] = importdata('cflie1.txt','\t');
[cflie2Log, delim2] = importdata('cflie2.txt','\t');
[cflie3Log, delim3] = importdata('cflie3.txt','\t');
[cflie4Log, delim4] = importdata('cflie4.txt','\t');
%
handTime = handLog.data(:,1);
handRoll = handLog.data(:,3);
handPitch = handLog.data(:,5);
handYaw = handLog.data(:,7);
handX = handLog.data(:,9); %Assigns Hand Data to user-friendly variable names
handY = handLog.data(:,11);
handZ = handLog.data(:,13);
handLoopTime = handLog.data(:,15);
handLoopTimeDelta = handLog.data(:,17);
%
cflie1Time = cflie1Log.data(:,1);
cflie1Roll = cflie1Log.data(:,3);
cflie1Pitch = cflie1Log.data(:,5); %Assigns Crazyflie1 Data to user-friendly variable names
cflie1Yaw = cflie1Log.data(:,7);
cflie1X = cflie1Log.data(:,9);
cflie1Y = cflie1Log.data(:,11);
cflie1Z = cflie1Log.data(:,13);
cflie1CamYaw = cflie1Log.data(:,15);
cflie1CorrectedYaw = cflie1Log.data(:,17);
cflie1LoopTimeTotal = cflie1Log.data(:,19);
cflie1LoopTimeTotalDelta = cflie1Log.data(:,21);
cflie1LoopTime = cflie1Log.data(:,23);
cflie1LoopTimeDelta = cflie1Log.data(:,25);
cflie1VrpnPacketDelta = cflie1Log.data(:,27);
cflie1VrpnPacketTime = cflie1Log.data(:,29);
cflie1VrpnPacketBackup = cflie1Log.data(:,31);
% cflie1XSetpoint = cflie1Log.data(:,33);
% cflie1YSetpoint = cflie1Log.data(:,35);
% cflie1ZSetpoint = cflie1Log.data(:,37);
% cflie1YawSetpoint = cflie1Log.data(:,39);
% cflie1PitchDesired = cflie1Log.data(:,41);
% cflie1RollDesired = cflie1Log.data(:,43);
% cflie1YawDesired = cflie1Log.data(:,45);
% cflie1ThrustDesired = cflie1Log.data(:,47);
% cflie1RadioRSSI = cflie1Log.data(:,49);
% cflie1CamYawRad = cflie1Log.data(:,51);
% cflie1CamPitchRad = cflie1Log.data(:,53);
% cflie1CamRollRad = cflie1Log.data(:,55);
% cflie1Motor1 = cflie1Log.data(:,57);
% cflie1Motor2 = cflie1Log.data(:,59);
% cflie1Motor3 = cflie1Log.data(:,61);
% cflie1Motor4 = cflie1Log.data(:,63);
% cflie1RollRate = cflie1Log.data(:,65);
% cflie1PitchRate = cflie1Log.data(:,67);
% cflie1YawRate = cflie1Log.data(:,69);
...
...
...
(same for Crazyflie 2, 3, and 4..)
...
...
</pre>
</code>
</blockquote>
::'''Note:''' This list needs to match the log file length that the Swarm Client creates (comment out as needed)
====Plotting X and Y Position of Crazyflies====
:The plots look like this:
::[[Image:XPositionPlot.png|400px]] [[Image:YPositionPlot.png|400px]]
<blockquote>
<code>
<pre>
%% Plot X Using ImportData
figure(8) %Plotting X-Positions
hold off
plot(cflie1Time,cflie1X, '-b')
hold on
% plot(cflie1Time,cflie1XSetpoint, '-.b')
%
plot(cflie2Time,cflie2X, '-g')
% plot(cflie2Time,cflie2XSetpoint, '-.g')
%
plot(cflie3Time,cflie3X, '-k')
% plot(cflie3Time,cflie3XSetpoint, '-.k')
%
plot(cflie4Time,cflie4X, '-y')
%
plot(handTime, handX, '-r')
% plot(cflie4Time,cflie4XSetpoint, '-.y')
title 'Crazyflie X-Positions'
legend('Crazyflie 1','Crazyflie 2','Crazyflie3', 'Crazyflie4', 'Hand')
xlabel 'Time (seconds)'
ylabel 'X-Position (m)'
grid on
% legend('Crazyflie 1','Setpoint', 'Crazyflie 2','Setpoint', 'Crazyflie3','Setpoint', 'Crazyflie4','Setpoint')
%
%
figure(9) %Plotting Y-Positions
hold off
plot(cflie1Time,cflie1Y, '-b')
hold on
% plot(cflie1Time,cflie1YSetpoint, '-.b')
%
plot(cflie2Time,cflie2Y, '-g')
% plot(cflie2Time,cflie2YSetpoint, '-.g')
%
plot(cflie3Time,cflie3Y, '-k')
% plot(cflie3Time,cflie3YSetpoint, '-.k')
%
plot(cflie4Time,cflie4Y, '-y')
% plot(cflie3Time,cflie3YSetpoint, '-.y')
%
plot(handTime, handY, '-r')
title 'Crazyflie Y-Positions'
legend('Crazyflie 1','Crazyflie 2','Crazyflie3', 'Crazyflie4', 'Hand')
% legend('Crazyflie 1', 'Setpoint','Crazyflie 2', 'Setpoint','Crazyflie3','Setpoint', 'Crazyflie4','Setpoint')
xlabel 'Time (seconds)'
ylabel 'Y-Position (m)'
grid on
</pre>
</code>
</blockquote>
====Plotting Loop Timing====
:This sub-routine plots a 3-piece subplot:
:#Z-Positions (Height) of all 4 Crazyflies
:#Time it takes for each Crazyflie Callback to finish
:#Time between subsequent Callback calls (Loop Deltas)
:Resulting in this Plot
::[[Image:HandModeTimingFigure.JPG|700px]]
<blockquote>
<code>
<pre>
figure(7)
subplot(3,1,1)
hold off
plot(cflie1Time,cflie1Z,'-b')
hold on
plot(cflie2Time,cflie2Z,'-g')
plot(cflie3Time,cflie3Z,'-k')
plot(cflie4Time,cflie4Z,'-y')
title 'Crazyflie Z (Height)'
legend('Crazyflie 1', 'Crazyflie2', 'Crazyflie3', 'Crazyflie4','Location','NorthWest')
ylabel 'Height (m)'
grid on
subplot(3,1,2)
hold off
plot(cflie1Time(4:end),cflie1LoopTime(4:end),'-b')
hold on
plot(cflie2Time(4:end),cflie2LoopTime(4:end),'-g')
plot(cflie3Time(4:end),cflie3LoopTime(4:end),'-k')
plot(cflie4Time(4:end),cflie4LoopTime(4:end),'-y')
title 'Loop Timing'
legend('Callback 1', 'Callback 2', 'Callback3', 'Callback4','Location','NorthWest')
ylabel 'Loop Time (seconds)'
grid on
subplot(3,1,3)
hold off
plot(cflie1Time(4:end),cflie1LoopTimeDelta(4:end),'-b')
hold on
plot(cflie2Time(4:end),cflie2LoopTimeDelta(4:end),'-g')
plot(cflie3Time(4:end),cflie3LoopTimeDelta(4:end),'-k')
plot(cflie4Time(4:end),cflie4LoopTimeDelta(4:end),'-y')
title 'Time Between Loop Calls'
legend('Callback 1', 'Callback 2', 'Callback3', 'Callback4','Location','NorthWest')
ylabel 'Loop Deltas (seconds)'
xlabel 'Time (seconds)'
grid on
</pre>
</code>
</blockquote>
====Hand Mode Position Plot====
:This sub-routine plots a 4-piece subplot:
:#X-Positions of all 4 Crazyflies and Hand
:#Y-Positions of all 4 Crazyflies and Hand
:#Z-Position of Hand (to show position based Gestures)
:#Pitch Angle of Hand (to show rotation based Gestures)
:Resulting in this Plot (w/o added annotations)
::[[Image:HandModePlot.jpg|700px]]
<blockquote>
<code>
<pre>
figure(12)
subplot(4,1,1)
hold off
plot(cflie1Time,cflie1X,'-b')
hold on
plot(cflie2Time,cflie2X,'-g')
plot(cflie3Time,cflie3X,'-k')
plot(cflie4Time,cflie4X,'-y')
plot(handTime, handX, '-r')
title 'X Position'
legend('Crazyflie 1', 'Crazyflie2', 'Crazyflie3', 'Crazyflie4','Hand')
ylabel 'X Position (m)'
grid on
subplot(4,1,2)
hold off
plot(cflie1Time,cflie1Y,'-b')
hold on
plot(cflie2Time,cflie2Y,'-g')
plot(cflie3Time,cflie3Y,'-k')
plot(cflie4Time,cflie4Y,'-y')
plot(handTime, handY, '-r')
title 'Y Position'
legend('Crazyflie 1', 'Crazyflie2', 'Crazyflie3', 'Crazyflie4','Hand')
ylabel 'Y Position (m)'
grid on
subplot(4,1,3)
hold off
plot(handTime, handZ, '-r')
title 'Hand Z Position'
legend('Hand Height')
ylabel 'Height (m)'
grid on
subplot(4,1,4)
hold off
plot(handTime, handPitch, '-r')
title 'Hand Pitch'
legend('Hand Pitch')
ylabel 'Angle (rad)'
grid on
</pre>
</code>
</blockquote>
===[http://wikis.ece.iastate.edu/robotic-agriculture-data-acquisition/index.php/Data_Analysis_Tool Universal Lab Parser (Alternative)]===
Alternatively, the lab has a unified logging format that can be read by a universal log parser. More information about this parsing method [http://wikis.ece.iastate.edu/robotic-agriculture-data-acquisition/index.php/Data_Analysis_Tool can be found here]
The Swarm Platform log files are compatible with this format and can be used just as any other lab log files. The problem is that this parser can '''only view a single text file at a time'''. This makes comparisons and plotting across all Crazyflies in the swarm very very difficult.
----
<center> '''Main Directory''' </center>
<center> [[Crazyflie Swarm|Crazyflie Swarm Home]] | [[PC Client Software]] | [[USB Radio]] | [[Firmware]] | [[FAQ]] </center>
<center> '''Modifications Directory''' </center>
<center> [[Controller]] | [[Logging]] | [[Keyboard Commands]] | [[USB Radio#Changing Radio Channel|Changing Radio Channel]] | [[Flight Modes]] | [[Callbacks]] | [[Adding a Crazyflie]] | [[Firmware]] </center>
4433451573fd161012bd01af3b9fe94105396103
241
240
2016-08-02T19:48:05Z
Jnoronha
3
/* MATLAB Parser */ removed the TODO
wikitext
text/x-wiki
The logging system is the most important analysis tool we have.
This allows us to export any variable data we want out to an external text file. This way we can use any data processor to parse the data. (Excel, MATLAB, R, etc.)
==Client-Side External Log Files==
We first need to initialize the log files and prepare them before each test.
:1. Create empty File Pointers (code in 'eris_vrpn.cpp')
<blockquote>
<code>
<pre>
FILE * outHand = NULL;
FILE * out1 = NULL;
FILE * out2 = NULL;
FILE * out3 = NULL;
FILE * out4 = NULL;
</pre>
</code>
</blockquote>
:2. Make sure Logging is Enabled (and Basic Logging if desired)
<blockquote>
<code>
<pre>
#define USE_VRPN 1
#define USE_KEYBOARD 1
#define USE_PRINTOUT 0
#define USE_LOGGING 1 <---//Enables Full Logging
#define USE_BASIC_LOGGING 1 <---//Only logs the necessities (FULL LOGGING MUST BE ENABLED FOR THIS TO WORK)
#define USE_PR_YAW_CORRECT 0
#define USE_HAND 1
</pre>
</code>
</blockquote>
:3. Create Log File Header (# = Log File Title, % = List of Variable Names, & = List of Variable Units)
::'''Note 1:''' This example is using BASIC_LOGGING 1,
::'''Note 2:''' Variables and units are separated by a double tab '\t\t' (Does not have to be '\t\t' any delimiter works)
<blockquote>
<code>
<pre>
const char * logHeaderHand = "#Hand Log File\n\
%Time\t\tPitch\t\tRoll\t\tYaw\t\tX\t\tY\t\tZ\t\tLoopTime\t\tLoopTimeDelta\n\
&sec\t\tdegrees\t\tdegrees\t\tdegrees\t\tmeters\t\tmeters\t\tmeters\t\tseconds\t\tseconds\n";
const char * logHeader1 = "#Crazyflie1 Log File\n\
%Time\t\tPitch\t\tRoll\t\tYaw\t\tX\t\tY\t\tZ\t\tCamYaw\t\tCorrectedYaw\t\tLoopTimeTotal\t\tLoopTimeTotalDelta\t\tLoopTime\t\tLoopTimeDelta\t\tvrpnPacketDelta\t\tvrpnPacketTime\t\tvrpnPacketBackup\t\tRadioRSSI\n\
&sec\t\tdegrees\t\tdegrees\t\tdegrees\t\tmeters\t\tmeters\t\tmeters\t\tdegrees\t\tdegrees\t\tseconds\t\tseconds\t\tseconds\t\tseconds\t\tseconds\t\tseconds\t\tpackets\t\tstrength\n";
const char * logHeader2 = "#Crazyflie2 Log File\n\
%Time\t\tPitch\t\tRoll\t\tYaw\t\tX\t\tY\t\tZ\t\tCamYaw\t\tCorrectedYaw\t\tLoopTimeTotal\t\tLoopTimeTotalDelta\t\tLoopTime\t\tLoopTimeDelta\t\tvrpnPacketDelta\t\tvrpnPacketTime\t\tvrpnPacketBackup\n\
&sec\t\tdegrees\t\tdegrees\t\tdegrees\t\tmeters\t\tmeters\t\tmeters\t\tdegrees\t\tdegrees\t\tseconds\t\tseconds\t\tseconds\t\tseconds\t\tseconds\t\tseconds\t\tpackets\n";
const char * logHeader3 = "#Crazyflie3 Log File\n\
%Time\t\tPitch\t\tRoll\t\tYaw\t\tX\t\tY\t\tZ\t\tCamYaw\t\tCorrectedYaw\t\tLoopTimeTotal\t\tLoopTimeTotalDelta\t\tLoopTime\t\tLoopTimeDelta\t\tvrpnPacketDelta\t\tvrpnPacketTime\t\tvrpnPacketBackup\n\
&sec\t\tdegrees\t\tdegrees\t\tdegrees\t\tmeters\t\tmeters\t\tmeters\t\tdegrees\t\tdegrees\t\tseconds\t\tseconds\t\tseconds\t\tseconds\t\tseconds\t\tseconds\t\tpackets\n";
const char * logHeader4 = "#Crazyflie4 Log File\n\
%Time\t\tPitch\t\tRoll\t\tYaw\t\tX\t\tY\t\tZ\t\tCamYaw\t\tCorrectedYaw\t\tLoopTimeTotal\t\tLoopTimeTotalDelta\t\tLoopTime\t\tLoopTimeDelta\t\tvrpnPacketDelta\t\tvrpnPacketTime\t\tvrpnPacketBackup\n\
&sec\t\tdegrees\t\tdegrees\t\tdegrees\t\tmeters\t\tmeters\t\tmeters\t\tdegrees\t\tdegrees\t\tseconds\t\tseconds\t\tseconds\t\tseconds\t\tseconds\t\tseconds\t\tpackets\n";
</pre>
</code>
</blockquote>
:4. Open External .txt file and Print Header into file
<blockquote>
<code>
<pre>
#if USE_HAND
outHand = fopen("hand.txt", "w"); //Opens text file with write permission
if(outHand == NULL)
{
printf("Could not open hand.log: errno %d\n", errno);
exit(-1);
}
fprintf(outHand, "%s\n", logHeaderHand); //Prints log header into corresponding file
#endif
if(cflieCopter1) //Checks to see if cflieCopter pointer has been initialized before opening file
{
out1 = fopen("cflie1.txt", "w");
if(out1 == NULL)
{
printf("Could not open cflie1.log: errno %d\n", errno);
exit(-1);
}
fprintf(out1, "%s\n", logHeader1);
}
if(cflieCopter2)
{
out2 = fopen("cflie2.txt", "w");
if(out2 == NULL)
{
printf("Could not open cflie2.log:errno %d\n", errno);
exit(-1);
}
fprintf(out2, "%s\n", logHeader2);
}
if(cflieCopter3)
{
out3 = fopen("cflie3.txt", "w");
if(out3 == NULL)
{
printf("Could not open cflie3.log:errno %d\n", errno);
exit(-1);
}
fprintf(out3, "%s\n", logHeader3);
}
if(cflieCopter4)
{
out4 = fopen("cflie4.txt", "w");
if(out4 == NULL)
{
printf("Could not open cflie4.log:errno %d\n", errno);
exit(-1);
}
fprintf(out4, "%s\n", logHeader4);
}
</pre>
</code>
</blockquote>
:5. Init has Completed (Start Program Loop) Prints Variable values to file...
::'''Note 1:''' This code is run at the end of the Callback for each Crazyflie initialized (Executes once per new data packet)
::'''Note 2:''' This example is using BASIC_LOGGING, and is only showing Crazyflie1's code.
<blockquote>
<code>
<pre>
fprintf(out1, "%.6f\t\t", cflieCopter1->currentTime() - initTime1 );
fprintf(out1, "%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.6f\t\t%.6f\t\t%.6f\t\t%.6f\t\t%.6f\t\t%.6f\t\t%d\t\t%d",
cflieCopter1->roll(),
cflieCopter1->pitch(),
quadYaw1,
t.pos[0],
t.pos[1],
-t.pos[2],
camYawDeg1,
correctedYaw1,
loopTimeTotal,
loopTimeTotalDelta,
loopTime1,
loopTime1Delta,
vrpnPacketDelta1,
vrpnPacketTime1,
vrpnPacketBackup1,
cflieCopter1->radioRSSI());
fprintf(out1, "\n");
</pre>
</code>
</blockquote>
:6. Close External .txt files before ending program
<blockquote>
<code>
<pre>
#if USE_LOGGING
#if USE_HAND
fclose(outHand);
#endif
#if NUM_QUADS >= 1
fclose(out1);
#endif
#if NUM_QUADS >= 2
fclose(out2);
#endif
#if NUM_QUADS >= 3
fclose(out3);
#endif
#if NUM_QUADS >= 4
fclose(out4);
#endif
#endif
</pre>
</code>
</blockquote>
==New Client Log Blocks==
In the Swarm Client there is a sub-system designed for creating and maintaining Log Blocks. Once you have [[:Firmware#Log Blocks|created a new log block in the Firmware]] that you want to utilize we can do the following:
:1. Create an Enable function for the New Log Block (code in ''CCrazyflie.cpp'')
<blockquote>
<code>
<pre>
void CCrazyflie::enableMagnetometerLogging() {
m_tocLogs->registerLoggingBlock("magnetometer", 1000);
m_tocLogs->startLogging("mag.x", "magnetometer");
m_tocLogs->startLogging("mag.y", "magnetometer");
m_tocLogs->startLogging("mag.z", "magnetometer");
}
</pre>
</code>
</blockquote>
::This will then register a log block called ''magnetometer'' on the Client, which will be updated every 1000 μs. It will then update the values listed in the block (X, Y, Z of the magnetometer).
::'''Note 1:''' The ''"mag.x"'' term must match the name defined in the Firmware log block (see [[:Firmware#Log Blocks|firmware example 1]])
::'''Note 2:''' The 2nd input to the ''startLogging'' function needs to match the name of the Client Log block we registered (in this case ''"magnetometer"'')
:2. Add the ''enableLogBlock'' function we just made to the list of Log blocks we want at startup (code in ''CCrazyflie.cpp''):
<blockquote>
<code>
<pre>
bool CCrazyflie::startLogging() {
// Register the desired sensor readings
this->enableStabilizerLogging();
// this->enableGyroscopeLogging();
// this->enableAccelerometerLogging();
this->enableBatteryLogging();
this->enableMagnetometerLogging(); <-----//This is the one we just made
// this->enableAltimeterLogging();
// this->enablePIDOutputLogging();
// this->enableRadioRSSILogging();
// this->enableMotorLogging();
return true;
}
</pre>
</code>
</blockquote>
::This ''startLogging'' function runs during Crazyflie startup and will start all the log blocks listed. As you can see we have some log blocks commented out currently so that we do NOT start those blocks.
:3. Create Functions to Read the variable values during runtime (code in ''CCrazyflie.cpp''):
<blockquote>
<code>
<pre>
float CCrazyflie::magX() {
return this->sensorDoubleValue("mag.x");
}
float CCrazyflie::magY() {
return this->sensorDoubleValue("mag.y");
}
float CCrazyflie::magZ() {
return this->sensorDoubleValue("mag.z");
}
</pre>
</code>
</blockquote>
::So now we can use these sensor values, from the Firmware, in the Client code with <code>magX1 = cflieCopter1->magX()</code>. This will store the sensor value in the Client-side variable ''magX1''.
:4. (OPTIONAL) We can also create a function to stop logging an individual log block in the Client (code in ''CCrazyflie.cpp'')
<blockquote>
<code>
<pre>
void CCrazyflie::disableMagnetometerLogging() {
m_tocLogs->unregisterLoggingBlock("magnetometer");
}
</pre>
</code>
</blockquote>
::This is straightforward, it just tells the client to stop logging this block.
:5. (OPTIONAL) And we can stop ALL log blocks in the client as well (code in ''CCrazyflie.cpp''):
<blockquote>
<code>
<pre>
bool CCrazyflie::stopLogging() {
this->disableStabilizerLogging();
this->disableGyroscopeLogging();
this->disableAccelerometerLogging();
this->disableBatteryLogging();
// this->disableMagnetometerLogging();
// this->disableAltimeterLogging();
// this->disablePIDOutputLogging();
this->disableRadioRSSILogging();
this->disableMotorLogging();
return true;
}
</pre>
</code>
</blockquote>
::This will disable ALL the logging blocks included in the list.
==MATLAB Parser==
We use a Matlab script to parse the log files.
===Multi-Logfile Parser===
The primary way we use to visualize the log files is via a very simple and messy MATLAB script. It consists of a bunch of sub-routines that were all thrown together into a single .m file.
====Import Log Data====
<blockquote>
<code>
<pre>
%% Crazyflie Logging Parser
[handLog, delimHand] = importdata('hand.txt','\t'); %Imports data from all 5 log files from the Swarm Client
[cflie1Log, delim1] = importdata('cflie1.txt','\t');
[cflie2Log, delim2] = importdata('cflie2.txt','\t');
[cflie3Log, delim3] = importdata('cflie3.txt','\t');
[cflie4Log, delim4] = importdata('cflie4.txt','\t');
%
handTime = handLog.data(:,1);
handRoll = handLog.data(:,3);
handPitch = handLog.data(:,5);
handYaw = handLog.data(:,7);
handX = handLog.data(:,9); %Assigns Hand Data to user-friendly variable names
handY = handLog.data(:,11);
handZ = handLog.data(:,13);
handLoopTime = handLog.data(:,15);
handLoopTimeDelta = handLog.data(:,17);
%
cflie1Time = cflie1Log.data(:,1);
cflie1Roll = cflie1Log.data(:,3);
cflie1Pitch = cflie1Log.data(:,5); %Assigns Crazyflie1 Data to user-friendly variable names
cflie1Yaw = cflie1Log.data(:,7);
cflie1X = cflie1Log.data(:,9);
cflie1Y = cflie1Log.data(:,11);
cflie1Z = cflie1Log.data(:,13);
cflie1CamYaw = cflie1Log.data(:,15);
cflie1CorrectedYaw = cflie1Log.data(:,17);
cflie1LoopTimeTotal = cflie1Log.data(:,19);
cflie1LoopTimeTotalDelta = cflie1Log.data(:,21);
cflie1LoopTime = cflie1Log.data(:,23);
cflie1LoopTimeDelta = cflie1Log.data(:,25);
cflie1VrpnPacketDelta = cflie1Log.data(:,27);
cflie1VrpnPacketTime = cflie1Log.data(:,29);
cflie1VrpnPacketBackup = cflie1Log.data(:,31);
% cflie1XSetpoint = cflie1Log.data(:,33);
% cflie1YSetpoint = cflie1Log.data(:,35);
% cflie1ZSetpoint = cflie1Log.data(:,37);
% cflie1YawSetpoint = cflie1Log.data(:,39);
% cflie1PitchDesired = cflie1Log.data(:,41);
% cflie1RollDesired = cflie1Log.data(:,43);
% cflie1YawDesired = cflie1Log.data(:,45);
% cflie1ThrustDesired = cflie1Log.data(:,47);
% cflie1RadioRSSI = cflie1Log.data(:,49);
% cflie1CamYawRad = cflie1Log.data(:,51);
% cflie1CamPitchRad = cflie1Log.data(:,53);
% cflie1CamRollRad = cflie1Log.data(:,55);
% cflie1Motor1 = cflie1Log.data(:,57);
% cflie1Motor2 = cflie1Log.data(:,59);
% cflie1Motor3 = cflie1Log.data(:,61);
% cflie1Motor4 = cflie1Log.data(:,63);
% cflie1RollRate = cflie1Log.data(:,65);
% cflie1PitchRate = cflie1Log.data(:,67);
% cflie1YawRate = cflie1Log.data(:,69);
...
...
...
(same for Crazyflie 2, 3, and 4..)
...
...
</pre>
</code>
</blockquote>
::'''Note:''' This list needs to match the log file length that the Swarm Client creates (comment out as needed)
====Plotting X and Y Position of Crazyflies====
:The plots look like this:
::[[Image:XPositionPlot.png|400px]] [[Image:YPositionPlot.png|400px]]
<blockquote>
<code>
<pre>
%% Plot X Using ImportData
figure(8) %Plotting X-Positions
hold off
plot(cflie1Time,cflie1X, '-b')
hold on
% plot(cflie1Time,cflie1XSetpoint, '-.b')
%
plot(cflie2Time,cflie2X, '-g')
% plot(cflie2Time,cflie2XSetpoint, '-.g')
%
plot(cflie3Time,cflie3X, '-k')
% plot(cflie3Time,cflie3XSetpoint, '-.k')
%
plot(cflie4Time,cflie4X, '-y')
%
plot(handTime, handX, '-r')
% plot(cflie4Time,cflie4XSetpoint, '-.y')
title 'Crazyflie X-Positions'
legend('Crazyflie 1','Crazyflie 2','Crazyflie3', 'Crazyflie4', 'Hand')
xlabel 'Time (seconds)'
ylabel 'X-Position (m)'
grid on
% legend('Crazyflie 1','Setpoint', 'Crazyflie 2','Setpoint', 'Crazyflie3','Setpoint', 'Crazyflie4','Setpoint')
%
%
figure(9) %Plotting Y-Positions
hold off
plot(cflie1Time,cflie1Y, '-b')
hold on
% plot(cflie1Time,cflie1YSetpoint, '-.b')
%
plot(cflie2Time,cflie2Y, '-g')
% plot(cflie2Time,cflie2YSetpoint, '-.g')
%
plot(cflie3Time,cflie3Y, '-k')
% plot(cflie3Time,cflie3YSetpoint, '-.k')
%
plot(cflie4Time,cflie4Y, '-y')
% plot(cflie3Time,cflie3YSetpoint, '-.y')
%
plot(handTime, handY, '-r')
title 'Crazyflie Y-Positions'
legend('Crazyflie 1','Crazyflie 2','Crazyflie3', 'Crazyflie4', 'Hand')
% legend('Crazyflie 1', 'Setpoint','Crazyflie 2', 'Setpoint','Crazyflie3','Setpoint', 'Crazyflie4','Setpoint')
xlabel 'Time (seconds)'
ylabel 'Y-Position (m)'
grid on
</pre>
</code>
</blockquote>
====Plotting Loop Timing====
:This sub-routine plots a 3-piece subplot:
:#Z-Positions (Height) of all 4 Crazyflies
:#Time it takes for each Crazyflie Callback to finish
:#Time between subsequent Callback calls (Loop Deltas)
:Resulting in this Plot
::[[Image:HandModeTimingFigure.JPG|700px]]
<blockquote>
<code>
<pre>
figure(7)
subplot(3,1,1)
hold off
plot(cflie1Time,cflie1Z,'-b')
hold on
plot(cflie2Time,cflie2Z,'-g')
plot(cflie3Time,cflie3Z,'-k')
plot(cflie4Time,cflie4Z,'-y')
title 'Crazyflie Z (Height)'
legend('Crazyflie 1', 'Crazyflie2', 'Crazyflie3', 'Crazyflie4','Location','NorthWest')
ylabel 'Height (m)'
grid on
subplot(3,1,2)
hold off
plot(cflie1Time(4:end),cflie1LoopTime(4:end),'-b')
hold on
plot(cflie2Time(4:end),cflie2LoopTime(4:end),'-g')
plot(cflie3Time(4:end),cflie3LoopTime(4:end),'-k')
plot(cflie4Time(4:end),cflie4LoopTime(4:end),'-y')
title 'Loop Timing'
legend('Callback 1', 'Callback 2', 'Callback3', 'Callback4','Location','NorthWest')
ylabel 'Loop Time (seconds)'
grid on
subplot(3,1,3)
hold off
plot(cflie1Time(4:end),cflie1LoopTimeDelta(4:end),'-b')
hold on
plot(cflie2Time(4:end),cflie2LoopTimeDelta(4:end),'-g')
plot(cflie3Time(4:end),cflie3LoopTimeDelta(4:end),'-k')
plot(cflie4Time(4:end),cflie4LoopTimeDelta(4:end),'-y')
title 'Time Between Loop Calls'
legend('Callback 1', 'Callback 2', 'Callback3', 'Callback4','Location','NorthWest')
ylabel 'Loop Deltas (seconds)'
xlabel 'Time (seconds)'
grid on
</pre>
</code>
</blockquote>
====Hand Mode Position Plot====
:This sub-routine plots a 4-piece subplot:
:#X-Positions of all 4 Crazyflies and Hand
:#Y-Positions of all 4 Crazyflies and Hand
:#Z-Position of Hand (to show position based Gestures)
:#Pitch Angle of Hand (to show rotation based Gestures)
:Resulting in this Plot (w/o added annotations)
::[[Image:HandModePlot.jpg|700px]]
<blockquote>
<code>
<pre>
figure(12)
subplot(4,1,1)
hold off
plot(cflie1Time,cflie1X,'-b')
hold on
plot(cflie2Time,cflie2X,'-g')
plot(cflie3Time,cflie3X,'-k')
plot(cflie4Time,cflie4X,'-y')
plot(handTime, handX, '-r')
title 'X Position'
legend('Crazyflie 1', 'Crazyflie2', 'Crazyflie3', 'Crazyflie4','Hand')
ylabel 'X Position (m)'
grid on
subplot(4,1,2)
hold off
plot(cflie1Time,cflie1Y,'-b')
hold on
plot(cflie2Time,cflie2Y,'-g')
plot(cflie3Time,cflie3Y,'-k')
plot(cflie4Time,cflie4Y,'-y')
plot(handTime, handY, '-r')
title 'Y Position'
legend('Crazyflie 1', 'Crazyflie2', 'Crazyflie3', 'Crazyflie4','Hand')
ylabel 'Y Position (m)'
grid on
subplot(4,1,3)
hold off
plot(handTime, handZ, '-r')
title 'Hand Z Position'
legend('Hand Height')
ylabel 'Height (m)'
grid on
subplot(4,1,4)
hold off
plot(handTime, handPitch, '-r')
title 'Hand Pitch'
legend('Hand Pitch')
ylabel 'Angle (rad)'
grid on
</pre>
</code>
</blockquote>
===[http://wikis.ece.iastate.edu/robotic-agriculture-data-acquisition/index.php/Data_Analysis_Tool Universal Lab Parser (Alternative)]===
Alternatively, the lab has a unified logging format that can be read by a universal log parser. More information about this parsing method [http://wikis.ece.iastate.edu/robotic-agriculture-data-acquisition/index.php/Data_Analysis_Tool can be found here]
The Swarm Platform log files are compatible with this format and can be used just as any other lab log files. The problem is that this parser can '''only view a single text file at a time'''. This makes comparisons and plotting across all Crazyflies in the swarm very very difficult.
----
<center> '''Main Directory''' </center>
<center> [[Crazyflie Swarm|Crazyflie Swarm Home]] | [[PC Client Software]] | [[USB Radio]] | [[Firmware]] | [[FAQ]] </center>
<center> '''Modifications Directory''' </center>
<center> [[Controller]] | [[Logging]] | [[Keyboard Commands]] | [[USB Radio#Changing Radio Channel|Changing Radio Channel]] | [[Flight Modes]] | [[Callbacks]] | [[Adding a Crazyflie]] | [[Firmware]] </center>
188340f58fc72b378c1e896f689282234ae9abde
242
241
2016-08-02T19:53:12Z
Jnoronha
3
/* MATLAB Parser */ added description to top and note about commented out matlab sub-routines
wikitext
text/x-wiki
The logging system is the most important analysis tool we have.
This allows us to export any variable data we want out to an external text file. This way we can use any data processor to parse the data. (Excel, MATLAB, R, etc.)
==Client-Side External Log Files==
We first need to initialize the log files and prepare them before each test.
:1. Create empty File Pointers (code in 'eris_vrpn.cpp')
<blockquote>
<code>
<pre>
FILE * outHand = NULL;
FILE * out1 = NULL;
FILE * out2 = NULL;
FILE * out3 = NULL;
FILE * out4 = NULL;
</pre>
</code>
</blockquote>
:2. Make sure Logging is Enabled (and Basic Logging if desired)
<blockquote>
<code>
<pre>
#define USE_VRPN 1
#define USE_KEYBOARD 1
#define USE_PRINTOUT 0
#define USE_LOGGING 1 <---//Enables Full Logging
#define USE_BASIC_LOGGING 1 <---//Only logs the necessities (FULL LOGGING MUST BE ENABLED FOR THIS TO WORK)
#define USE_PR_YAW_CORRECT 0
#define USE_HAND 1
</pre>
</code>
</blockquote>
:3. Create Log File Header (# = Log File Title, % = List of Variable Names, & = List of Variable Units)
::'''Note 1:''' This example is using BASIC_LOGGING 1,
::'''Note 2:''' Variables and units are separated by a double tab '\t\t' (Does not have to be '\t\t' any delimiter works)
<blockquote>
<code>
<pre>
const char * logHeaderHand = "#Hand Log File\n\
%Time\t\tPitch\t\tRoll\t\tYaw\t\tX\t\tY\t\tZ\t\tLoopTime\t\tLoopTimeDelta\n\
&sec\t\tdegrees\t\tdegrees\t\tdegrees\t\tmeters\t\tmeters\t\tmeters\t\tseconds\t\tseconds\n";
const char * logHeader1 = "#Crazyflie1 Log File\n\
%Time\t\tPitch\t\tRoll\t\tYaw\t\tX\t\tY\t\tZ\t\tCamYaw\t\tCorrectedYaw\t\tLoopTimeTotal\t\tLoopTimeTotalDelta\t\tLoopTime\t\tLoopTimeDelta\t\tvrpnPacketDelta\t\tvrpnPacketTime\t\tvrpnPacketBackup\t\tRadioRSSI\n\
&sec\t\tdegrees\t\tdegrees\t\tdegrees\t\tmeters\t\tmeters\t\tmeters\t\tdegrees\t\tdegrees\t\tseconds\t\tseconds\t\tseconds\t\tseconds\t\tseconds\t\tseconds\t\tpackets\t\tstrength\n";
const char * logHeader2 = "#Crazyflie2 Log File\n\
%Time\t\tPitch\t\tRoll\t\tYaw\t\tX\t\tY\t\tZ\t\tCamYaw\t\tCorrectedYaw\t\tLoopTimeTotal\t\tLoopTimeTotalDelta\t\tLoopTime\t\tLoopTimeDelta\t\tvrpnPacketDelta\t\tvrpnPacketTime\t\tvrpnPacketBackup\n\
&sec\t\tdegrees\t\tdegrees\t\tdegrees\t\tmeters\t\tmeters\t\tmeters\t\tdegrees\t\tdegrees\t\tseconds\t\tseconds\t\tseconds\t\tseconds\t\tseconds\t\tseconds\t\tpackets\n";
const char * logHeader3 = "#Crazyflie3 Log File\n\
%Time\t\tPitch\t\tRoll\t\tYaw\t\tX\t\tY\t\tZ\t\tCamYaw\t\tCorrectedYaw\t\tLoopTimeTotal\t\tLoopTimeTotalDelta\t\tLoopTime\t\tLoopTimeDelta\t\tvrpnPacketDelta\t\tvrpnPacketTime\t\tvrpnPacketBackup\n\
&sec\t\tdegrees\t\tdegrees\t\tdegrees\t\tmeters\t\tmeters\t\tmeters\t\tdegrees\t\tdegrees\t\tseconds\t\tseconds\t\tseconds\t\tseconds\t\tseconds\t\tseconds\t\tpackets\n";
const char * logHeader4 = "#Crazyflie4 Log File\n\
%Time\t\tPitch\t\tRoll\t\tYaw\t\tX\t\tY\t\tZ\t\tCamYaw\t\tCorrectedYaw\t\tLoopTimeTotal\t\tLoopTimeTotalDelta\t\tLoopTime\t\tLoopTimeDelta\t\tvrpnPacketDelta\t\tvrpnPacketTime\t\tvrpnPacketBackup\n\
&sec\t\tdegrees\t\tdegrees\t\tdegrees\t\tmeters\t\tmeters\t\tmeters\t\tdegrees\t\tdegrees\t\tseconds\t\tseconds\t\tseconds\t\tseconds\t\tseconds\t\tseconds\t\tpackets\n";
</pre>
</code>
</blockquote>
:4. Open External .txt file and Print Header into file
<blockquote>
<code>
<pre>
#if USE_HAND
outHand = fopen("hand.txt", "w"); //Opens text file with write permission
if(outHand == NULL)
{
printf("Could not open hand.log: errno %d\n", errno);
exit(-1);
}
fprintf(outHand, "%s\n", logHeaderHand); //Prints log header into corresponding file
#endif
if(cflieCopter1) //Checks to see if cflieCopter pointer has been initialized before opening file
{
out1 = fopen("cflie1.txt", "w");
if(out1 == NULL)
{
printf("Could not open cflie1.log: errno %d\n", errno);
exit(-1);
}
fprintf(out1, "%s\n", logHeader1);
}
if(cflieCopter2)
{
out2 = fopen("cflie2.txt", "w");
if(out2 == NULL)
{
printf("Could not open cflie2.log:errno %d\n", errno);
exit(-1);
}
fprintf(out2, "%s\n", logHeader2);
}
if(cflieCopter3)
{
out3 = fopen("cflie3.txt", "w");
if(out3 == NULL)
{
printf("Could not open cflie3.log:errno %d\n", errno);
exit(-1);
}
fprintf(out3, "%s\n", logHeader3);
}
if(cflieCopter4)
{
out4 = fopen("cflie4.txt", "w");
if(out4 == NULL)
{
printf("Could not open cflie4.log:errno %d\n", errno);
exit(-1);
}
fprintf(out4, "%s\n", logHeader4);
}
</pre>
</code>
</blockquote>
:5. Init has Completed (Start Program Loop) Prints Variable values to file...
::'''Note 1:''' This code is run at the end of the Callback for each Crazyflie initialized (Executes once per new data packet)
::'''Note 2:''' This example is using BASIC_LOGGING, and is only showing Crazyflie1's code.
<blockquote>
<code>
<pre>
fprintf(out1, "%.6f\t\t", cflieCopter1->currentTime() - initTime1 );
fprintf(out1, "%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.3f\t\t%.6f\t\t%.6f\t\t%.6f\t\t%.6f\t\t%.6f\t\t%.6f\t\t%d\t\t%d",
cflieCopter1->roll(),
cflieCopter1->pitch(),
quadYaw1,
t.pos[0],
t.pos[1],
-t.pos[2],
camYawDeg1,
correctedYaw1,
loopTimeTotal,
loopTimeTotalDelta,
loopTime1,
loopTime1Delta,
vrpnPacketDelta1,
vrpnPacketTime1,
vrpnPacketBackup1,
cflieCopter1->radioRSSI());
fprintf(out1, "\n");
</pre>
</code>
</blockquote>
:6. Close External .txt files before ending program
<blockquote>
<code>
<pre>
#if USE_LOGGING
#if USE_HAND
fclose(outHand);
#endif
#if NUM_QUADS >= 1
fclose(out1);
#endif
#if NUM_QUADS >= 2
fclose(out2);
#endif
#if NUM_QUADS >= 3
fclose(out3);
#endif
#if NUM_QUADS >= 4
fclose(out4);
#endif
#endif
</pre>
</code>
</blockquote>
==New Client Log Blocks==
In the Swarm Client there is a sub-system designed for creating and maintaining Log Blocks. Once you have [[:Firmware#Log Blocks|created a new log block in the Firmware]] that you want to utilize we can do the following:
:1. Create an Enable function for the New Log Block (code in ''CCrazyflie.cpp'')
<blockquote>
<code>
<pre>
void CCrazyflie::enableMagnetometerLogging() {
m_tocLogs->registerLoggingBlock("magnetometer", 1000);
m_tocLogs->startLogging("mag.x", "magnetometer");
m_tocLogs->startLogging("mag.y", "magnetometer");
m_tocLogs->startLogging("mag.z", "magnetometer");
}
</pre>
</code>
</blockquote>
::This will then register a log block called ''magnetometer'' on the Client, which will be updated every 1000 μs. It will then update the values listed in the block (X, Y, Z of the magnetometer).
::'''Note 1:''' The ''"mag.x"'' term must match the name defined in the Firmware log block (see [[:Firmware#Log Blocks|firmware example 1]])
::'''Note 2:''' The 2nd input to the ''startLogging'' function needs to match the name of the Client Log block we registered (in this case ''"magnetometer"'')
:2. Add the ''enableLogBlock'' function we just made to the list of Log blocks we want at startup (code in ''CCrazyflie.cpp''):
<blockquote>
<code>
<pre>
bool CCrazyflie::startLogging() {
// Register the desired sensor readings
this->enableStabilizerLogging();
// this->enableGyroscopeLogging();
// this->enableAccelerometerLogging();
this->enableBatteryLogging();
this->enableMagnetometerLogging(); <-----//This is the one we just made
// this->enableAltimeterLogging();
// this->enablePIDOutputLogging();
// this->enableRadioRSSILogging();
// this->enableMotorLogging();
return true;
}
</pre>
</code>
</blockquote>
::This ''startLogging'' function runs during Crazyflie startup and will start all the log blocks listed. As you can see we have some log blocks commented out currently so that we do NOT start those blocks.
:3. Create Functions to Read the variable values during runtime (code in ''CCrazyflie.cpp''):
<blockquote>
<code>
<pre>
float CCrazyflie::magX() {
return this->sensorDoubleValue("mag.x");
}
float CCrazyflie::magY() {
return this->sensorDoubleValue("mag.y");
}
float CCrazyflie::magZ() {
return this->sensorDoubleValue("mag.z");
}
</pre>
</code>
</blockquote>
::So now we can use these sensor values, from the Firmware, in the Client code with <code>magX1 = cflieCopter1->magX()</code>. This will store the sensor value in the Client-side variable ''magX1''.
:4. (OPTIONAL) We can also create a function to stop logging an individual log block in the Client (code in ''CCrazyflie.cpp'')
<blockquote>
<code>
<pre>
void CCrazyflie::disableMagnetometerLogging() {
m_tocLogs->unregisterLoggingBlock("magnetometer");
}
</pre>
</code>
</blockquote>
::This is straightforward, it just tells the client to stop logging this block.
:5. (OPTIONAL) And we can stop ALL log blocks in the client as well (code in ''CCrazyflie.cpp''):
<blockquote>
<code>
<pre>
bool CCrazyflie::stopLogging() {
this->disableStabilizerLogging();
this->disableGyroscopeLogging();
this->disableAccelerometerLogging();
this->disableBatteryLogging();
// this->disableMagnetometerLogging();
// this->disableAltimeterLogging();
// this->disablePIDOutputLogging();
this->disableRadioRSSILogging();
this->disableMotorLogging();
return true;
}
</pre>
</code>
</blockquote>
::This will disable ALL the logging blocks included in the list.
==MATLAB Parser==
We use a Matlab script to parse the log files. You can use any program you want to parse the data if you are more comfortable with it, below you will find some details on how we parse the log-files.
===Multi-Logfile Parser===
The primary way we use to visualize the log files is via a very simple and messy MATLAB script. It consists of a bunch of sub-routines that were all thrown together into a single .m file.
====Import Log Data====
<blockquote>
<code>
<pre>
%% Crazyflie Logging Parser
[handLog, delimHand] = importdata('hand.txt','\t'); %Imports data from all 5 log files from the Swarm Client
[cflie1Log, delim1] = importdata('cflie1.txt','\t');
[cflie2Log, delim2] = importdata('cflie2.txt','\t');
[cflie3Log, delim3] = importdata('cflie3.txt','\t');
[cflie4Log, delim4] = importdata('cflie4.txt','\t');
%
handTime = handLog.data(:,1);
handRoll = handLog.data(:,3);
handPitch = handLog.data(:,5);
handYaw = handLog.data(:,7);
handX = handLog.data(:,9); %Assigns Hand Data to user-friendly variable names
handY = handLog.data(:,11);
handZ = handLog.data(:,13);
handLoopTime = handLog.data(:,15);
handLoopTimeDelta = handLog.data(:,17);
%
cflie1Time = cflie1Log.data(:,1);
cflie1Roll = cflie1Log.data(:,3);
cflie1Pitch = cflie1Log.data(:,5); %Assigns Crazyflie1 Data to user-friendly variable names
cflie1Yaw = cflie1Log.data(:,7);
cflie1X = cflie1Log.data(:,9);
cflie1Y = cflie1Log.data(:,11);
cflie1Z = cflie1Log.data(:,13);
cflie1CamYaw = cflie1Log.data(:,15);
cflie1CorrectedYaw = cflie1Log.data(:,17);
cflie1LoopTimeTotal = cflie1Log.data(:,19);
cflie1LoopTimeTotalDelta = cflie1Log.data(:,21);
cflie1LoopTime = cflie1Log.data(:,23);
cflie1LoopTimeDelta = cflie1Log.data(:,25);
cflie1VrpnPacketDelta = cflie1Log.data(:,27);
cflie1VrpnPacketTime = cflie1Log.data(:,29);
cflie1VrpnPacketBackup = cflie1Log.data(:,31);
% cflie1XSetpoint = cflie1Log.data(:,33);
% cflie1YSetpoint = cflie1Log.data(:,35);
% cflie1ZSetpoint = cflie1Log.data(:,37);
% cflie1YawSetpoint = cflie1Log.data(:,39);
% cflie1PitchDesired = cflie1Log.data(:,41);
% cflie1RollDesired = cflie1Log.data(:,43);
% cflie1YawDesired = cflie1Log.data(:,45);
% cflie1ThrustDesired = cflie1Log.data(:,47);
% cflie1RadioRSSI = cflie1Log.data(:,49);
% cflie1CamYawRad = cflie1Log.data(:,51);
% cflie1CamPitchRad = cflie1Log.data(:,53);
% cflie1CamRollRad = cflie1Log.data(:,55);
% cflie1Motor1 = cflie1Log.data(:,57);
% cflie1Motor2 = cflie1Log.data(:,59);
% cflie1Motor3 = cflie1Log.data(:,61);
% cflie1Motor4 = cflie1Log.data(:,63);
% cflie1RollRate = cflie1Log.data(:,65);
% cflie1PitchRate = cflie1Log.data(:,67);
% cflie1YawRate = cflie1Log.data(:,69);
...
...
...
(same for Crazyflie 2, 3, and 4..)
...
...
</pre>
</code>
</blockquote>
::'''Note:''' This list needs to match the log file length that the Swarm Client creates (comment out as needed)
====Plotting X and Y Position of Crazyflies====
:The plots look like this:
::[[Image:XPositionPlot.png|400px]] [[Image:YPositionPlot.png|400px]]
<blockquote>
<code>
<pre>
%% Plot X Using ImportData
figure(8) %Plotting X-Positions
hold off
plot(cflie1Time,cflie1X, '-b')
hold on
% plot(cflie1Time,cflie1XSetpoint, '-.b')
%
plot(cflie2Time,cflie2X, '-g')
% plot(cflie2Time,cflie2XSetpoint, '-.g')
%
plot(cflie3Time,cflie3X, '-k')
% plot(cflie3Time,cflie3XSetpoint, '-.k')
%
plot(cflie4Time,cflie4X, '-y')
%
plot(handTime, handX, '-r')
% plot(cflie4Time,cflie4XSetpoint, '-.y')
title 'Crazyflie X-Positions'
legend('Crazyflie 1','Crazyflie 2','Crazyflie3', 'Crazyflie4', 'Hand')
xlabel 'Time (seconds)'
ylabel 'X-Position (m)'
grid on
% legend('Crazyflie 1','Setpoint', 'Crazyflie 2','Setpoint', 'Crazyflie3','Setpoint', 'Crazyflie4','Setpoint')
%
%
figure(9) %Plotting Y-Positions
hold off
plot(cflie1Time,cflie1Y, '-b')
hold on
% plot(cflie1Time,cflie1YSetpoint, '-.b')
%
plot(cflie2Time,cflie2Y, '-g')
% plot(cflie2Time,cflie2YSetpoint, '-.g')
%
plot(cflie3Time,cflie3Y, '-k')
% plot(cflie3Time,cflie3YSetpoint, '-.k')
%
plot(cflie4Time,cflie4Y, '-y')
% plot(cflie3Time,cflie3YSetpoint, '-.y')
%
plot(handTime, handY, '-r')
title 'Crazyflie Y-Positions'
legend('Crazyflie 1','Crazyflie 2','Crazyflie3', 'Crazyflie4', 'Hand')
% legend('Crazyflie 1', 'Setpoint','Crazyflie 2', 'Setpoint','Crazyflie3','Setpoint', 'Crazyflie4','Setpoint')
xlabel 'Time (seconds)'
ylabel 'Y-Position (m)'
grid on
</pre>
</code>
</blockquote>
====Plotting Loop Timing====
:This sub-routine plots a 3-piece subplot:
:#Z-Positions (Height) of all 4 Crazyflies
:#Time it takes for each Crazyflie Callback to finish
:#Time between subsequent Callback calls (Loop Deltas)
:Resulting in this Plot
::[[Image:HandModeTimingFigure.JPG|700px]]
<blockquote>
<code>
<pre>
figure(7)
subplot(3,1,1)
hold off
plot(cflie1Time,cflie1Z,'-b')
hold on
plot(cflie2Time,cflie2Z,'-g')
plot(cflie3Time,cflie3Z,'-k')
plot(cflie4Time,cflie4Z,'-y')
title 'Crazyflie Z (Height)'
legend('Crazyflie 1', 'Crazyflie2', 'Crazyflie3', 'Crazyflie4','Location','NorthWest')
ylabel 'Height (m)'
grid on
subplot(3,1,2)
hold off
plot(cflie1Time(4:end),cflie1LoopTime(4:end),'-b')
hold on
plot(cflie2Time(4:end),cflie2LoopTime(4:end),'-g')
plot(cflie3Time(4:end),cflie3LoopTime(4:end),'-k')
plot(cflie4Time(4:end),cflie4LoopTime(4:end),'-y')
title 'Loop Timing'
legend('Callback 1', 'Callback 2', 'Callback3', 'Callback4','Location','NorthWest')
ylabel 'Loop Time (seconds)'
grid on
subplot(3,1,3)
hold off
plot(cflie1Time(4:end),cflie1LoopTimeDelta(4:end),'-b')
hold on
plot(cflie2Time(4:end),cflie2LoopTimeDelta(4:end),'-g')
plot(cflie3Time(4:end),cflie3LoopTimeDelta(4:end),'-k')
plot(cflie4Time(4:end),cflie4LoopTimeDelta(4:end),'-y')
title 'Time Between Loop Calls'
legend('Callback 1', 'Callback 2', 'Callback3', 'Callback4','Location','NorthWest')
ylabel 'Loop Deltas (seconds)'
xlabel 'Time (seconds)'
grid on
</pre>
</code>
</blockquote>
====Hand Mode Position Plot====
:This sub-routine plots a 4-piece subplot:
:#X-Positions of all 4 Crazyflies and Hand
:#Y-Positions of all 4 Crazyflies and Hand
:#Z-Position of Hand (to show position based Gestures)
:#Pitch Angle of Hand (to show rotation based Gestures)
:Resulting in this Plot (w/o added annotations)
::[[Image:HandModePlot.jpg|700px]]
<blockquote>
<code>
<pre>
figure(12)
subplot(4,1,1)
hold off
plot(cflie1Time,cflie1X,'-b')
hold on
plot(cflie2Time,cflie2X,'-g')
plot(cflie3Time,cflie3X,'-k')
plot(cflie4Time,cflie4X,'-y')
plot(handTime, handX, '-r')
title 'X Position'
legend('Crazyflie 1', 'Crazyflie2', 'Crazyflie3', 'Crazyflie4','Hand')
ylabel 'X Position (m)'
grid on
subplot(4,1,2)
hold off
plot(cflie1Time,cflie1Y,'-b')
hold on
plot(cflie2Time,cflie2Y,'-g')
plot(cflie3Time,cflie3Y,'-k')
plot(cflie4Time,cflie4Y,'-y')
plot(handTime, handY, '-r')
title 'Y Position'
legend('Crazyflie 1', 'Crazyflie2', 'Crazyflie3', 'Crazyflie4','Hand')
ylabel 'Y Position (m)'
grid on
subplot(4,1,3)
hold off
plot(handTime, handZ, '-r')
title 'Hand Z Position'
legend('Hand Height')
ylabel 'Height (m)'
grid on
subplot(4,1,4)
hold off
plot(handTime, handPitch, '-r')
title 'Hand Pitch'
legend('Hand Pitch')
ylabel 'Angle (rad)'
grid on
</pre>
</code>
</blockquote>
'''NOTE:''' There are many other sub-routines in the MATLAB script that we are not currently using, this is just a sample of some of the more useful data visualization methods we have in place already. You can see more in ''cflieLogParser.m'' (located in the Swarm Client directory).
===[http://wikis.ece.iastate.edu/robotic-agriculture-data-acquisition/index.php/Data_Analysis_Tool Universal Lab Parser (Alternative)]===
Alternatively, the lab has a unified logging format that can be read by a universal log parser. More information about this parsing method [http://wikis.ece.iastate.edu/robotic-agriculture-data-acquisition/index.php/Data_Analysis_Tool can be found here]
The Swarm Platform log files are compatible with this format and can be used just as any other lab log files. The problem is that this parser can '''only view a single text file at a time'''. This makes comparisons and plotting across all Crazyflies in the swarm very very difficult.
----
<center> '''Main Directory''' </center>
<center> [[Crazyflie Swarm|Crazyflie Swarm Home]] | [[PC Client Software]] | [[USB Radio]] | [[Firmware]] | [[FAQ]] </center>
<center> '''Modifications Directory''' </center>
<center> [[Controller]] | [[Logging]] | [[Keyboard Commands]] | [[USB Radio#Changing Radio Channel|Changing Radio Channel]] | [[Flight Modes]] | [[Callbacks]] | [[Adding a Crazyflie]] | [[Firmware]] </center>
9312cbcce1cf7c213864db579c28476b7feb0ab7
File:XPositionPlot.png
6
67
235
2016-08-02T19:24:31Z
Jnoronha
3
X position plot produced by the matlab logfile parser
wikitext
text/x-wiki
X position plot produced by the matlab logfile parser
e330d18c0d830813b11e4a5551b13d1e20d2a2e5
File:YPositionPlot.png
6
68
236
2016-08-02T19:24:48Z
Jnoronha
3
Y position plot produced by the matlab logfile parser
wikitext
text/x-wiki
Y position plot produced by the matlab logfile parser
0cbfa9ce48512c39aeee38c0b9d34ec8a20e813d
File:HandModePlot.jpg
6
69
237
2016-08-02T19:25:18Z
Jnoronha
3
Hand Mode demo plot produced by the matlab logfile parser
wikitext
text/x-wiki
Hand Mode demo plot produced by the matlab logfile parser
b68031a6bf9dcc7b0a69a5763515d6025eda6087
File:HandModeTimingFigure.JPG
6
70
238
2016-08-02T19:25:43Z
Jnoronha
3
Hand Mode timing plot produced by the matlab logfile parser
wikitext
text/x-wiki
Hand Mode timing plot produced by the matlab logfile parser
ebaca8b8857776b9ef950bf6d7cdf786cbbf37f1
FAQ
0
40
244
136
2016-08-02T19:55:22Z
Jnoronha
3
added matlab parser
wikitext
text/x-wiki
Here you can find some Frequently Asked Questions:
:'''1. How do I change the Radio Channel?'''
::Find out here: [[:USB Radio#Changing Radio Channel|Changing the Radio Channel]]
:'''2. How do I use Log Blocks?'''
::*Creating and using [[:Logging#Client-Side External Log Files|External Client-side Log Files]]
::*Creating [[:Firmware#New Firmware Log Blocks|New Log Blocks in Firmware]]
::*Creating and Using [[:Logging#New Client Log Blocks|New Log Blocks in Client]]
:'''3. I just want to run the code, how do I run it?'''
::See [[:PC Client Software#Using the Swarm Client|Using the Swarm Client]]
:'''4. What are the Keyboard Commands for flying the Crazyflie?'''
::You can find a full list of all the Key Commands in [[:Keyboard Commands]]
::(Alternatively: See '''Step 4''' of [[:PC Client Software#Using the Swarm Client|Using the Swarm Client]])
:'''5. How do I plot the Log Files that the Crazyflie Swarm Creates?'''
::See the [[:Logging#MATLAB Parser|MATLAB Parser]] section for examples.
----
<center> '''Main Directory''' </center>
<center> [[Crazyflie Swarm|Crazyflie Swarm Home]] | [[PC Client Software]] | [[USB Radio]] | [[Firmware]] | [[FAQ]] </center>
<center> '''Modifications Directory''' </center>
<center> [[Controller]] | [[Logging]] | [[Keyboard Commands]] | [[USB Radio#Changing Radio Channel|Changing Radio Channel]] | [[Flight Modes]] | [[Callbacks]] | [[Adding a Crazyflie]] | [[Firmware]] </center>
1b2d0d04b3d42a0b8e78bcd9d5b2e1797dc4488c
Crazyflie Swarm
0
2
245
177
2016-08-02T19:59:51Z
Jnoronha
3
added swarm architecture
wikitext
text/x-wiki
The Crazyflie Swarm is a Networked Control platform designed for students to learn more about control and for researchers that wish to apply their research in practice. Platform development was started during the Summer of 2015 and continues to this day.
Here you will find descriptions on how the platform works, how you can use it, and how you can get involved in developing the platform further!
== Frequently Asked Questions ==
For help with common problems and troubleshooting please see the [[FAQ]].
== Background ==
The Crazyflie Swarm platform is based off of the ''Crazyflie'' Nano-quadcopter produced and maintained by [https://www.bitcraze.io/ Bitcraze]. The ''Crazyflie'' is completely open-source so we are able to look at and modify any part of the code and customize it to our needs.
=== Major Platform Components: ===
[[Image: High_Level_Figure_(Single_Radio_Single_Crazyflie_NO_NUMBERS_CROPPED).jpg|thumb|right|A high level overview of the Crazyflie Platform]]
*[[PC Client Software]]
*[[Firmware]]
*[[USB Radio]]
== Modifying the Platform ==
[[Image:SingleRadioMultiCrazyflie.jpg|thumb|right|A high level overview of the Swarm Platform we created]]
*[[Controller]]
*[[Logging]]
*[[Keyboard Commands]]
*[[USB Radio#Changing Radio Channel|Changing Radio Channel]]
*[[Flight Modes]]
*[[Callbacks]]
*[[Adding a Crazyflie]]
*[[:Firmware]]
==Future Project Ideas==
The whole concept of this Platform is to constantly expand its capabilities. If you are interested in developing this platform further here are some ideas to get you started! Additional details on any of these ideas can be found on the [[Future Project Ideas]] page.
*[[:Future Project Ideas#Migrating Swarm Client PID's to Firmware|Migrating Swarm Client PID's to Firmware]]
*[[:Future Project Ideas#Model Development/Verification and Tuning X, Y, and Z Location PID's|Model Development/Verification and Tuning X, Y, and Z Location PID's]]
*[[:Future Project Ideas#Adding Parameter Support to Swarm Client|Adding Parameter Support to Swarm Client]]
*[[:Future Project Ideas#Threading Each USB Radio to speed up Computation|Threading Each USB Radio to speed up Computation]]
*[[:Future Project Ideas#Developing New Controllers for the Crazyflie (pending Model Development)|Developing New Controllers for the Crazyflie (pending Model Development)]]
*[[:Future Project Ideas#Develop Communications Network Between Crazyflies|Develop Communications Network Between Crazyflies]]
*[[:Future Project Ideas#Trilateration Position Estimation using a Swarm|Trilateration Position Estimation using a Swarm]]
== [https://wiki.bitcraze.io/ Bitcraze Wiki] ==
Bitcraze maintains their own wiki on the many Crazyflie systems. If you can't find what you are looking for here, chances are they will have something to help.
a0d387286b6f276a370f5f1679b4b5b51d852570
File:MeasureVwheel.jpg
6
71
246
2016-08-02T20:00:49Z
Pfuhing
5
wikitext
text/x-wiki
da39a3ee5e6b4b0d3255bfef95601890afd80709
File:PowerSplitter.jpg
6
72
250
2016-08-02T20:15:42Z
Pfuhing
5
wikitext
text/x-wiki
da39a3ee5e6b4b0d3255bfef95601890afd80709
Data Collection and Simulation Comparison
0
50
251
249
2016-08-02T20:21:53Z
Pfuhing
5
/* Quad Battery */
wikitext
text/x-wiki
This page will take you though setting up and testing RADA, retrieving the log file and other necessary data to run a simulation of that test and processing the data in MATLAB. Then actually running the simulation of RADA in Simulink.
== Setting Up a RADA Test ==
Testing RADA is not overly difficult once you get the hang of the steps to setup RADA. The following steps may seem like a long process to go from starting the testing process to having completed simulation and plotting of the test results but this whole test procedure (with the exception of battery charging) can be completed in about 15-20 minutes. These steps are meant to be as detailed as possible in order to help new users of RADA to get up and running as quickly as possible.
'''<span style="color:red">NOTE: Always run RADA with at least 2 people!</span>''' The pendulum arm can crash into the ground if the network starts to drop packets and one person cannot give commands to RADA and spot the pendulum. This is a safety issue for both you and the RADA platform.
=== Charging batteries ===
The lab currently uses mostly Hyperion batteries. We charge our batteries with a Hyperion EOS 1420i Net3 battery charger. For some general information about how to use this charger see [https://www.youtube.com/watch?v=-ox3EpzvsJ8 this video.]. In the lab we power this charger using the old Kepco Power supplu because it is the only power supply that we have that can supply enough current. Make sure that the power supply is set to an output voltage between 10.5V-29V.
{| class="wikitable" style="text-align:center"
|-
| [[Image:ChargerPowerSupplyOff.JPG|400px]]
| [[Image:ChargerPowerSuplyOn.JPG|400px]]
|-
| Kepco Power Supply off.
| Kepco Power Supply on with correct voltage supply range.
|}
While the YouTube video linked above should explain how to use the charger. Currently three different Lithium polymer batteries (Lipo): 1600 mAh 2-cell Lipo for the wheels, 2600 mAh 2-cell Lipo for the electronics of Eris, and a 2600 mAh 4-cell Lipo. The 1600 mAh 2-cell Lipo can be charged using memory slot 2 of the charger. The 2600 mAh 2-cell Lipos can be charged using memory slot 3 for fast charging and memory slot 4 for slower charging (use this if the battery gets run really low for 10-20 minutes then switch to fast charging). The 2600 mAh 4-cell Lipo can be charged using memory slot 8. The 1600 mAh 2-cell and 2600 mAr 4-cell generally charge in 10-20 minutes apiece while I generally fine it takes the 2600 mAh 2-cell up to 70 minutes to charge fully.
=== Setting up the camera system ===
The camera system is run on the windows computer CO3050-07. You can log into this computer using a local microcart username and password which is not posted here for security reasons but any one who works in the lab should know it. Once logged in look for Tracking Tools in the start menu or look for the shortcut shown below:
[[Image:TrackingTools_shortcut.PNG|thumb|center|Tracking Tools shortcut]]
Once the program opens the screen should look something like this:
[[Image:NewTrackingTools.PNG|800px]]
In the Tracking Tools Quick Start pop up menu select Open Existing Project and then navigate to ''D:\Optitrack_Configuration'' (It should open to this directory by default) and select the most recent Tracking Tools project. It should be named like ''TrackingToolsProject YYYY-MM-DD timeStamp.ttp''. This is normally the most recently edited file when sorting by data modified. The most recent one as of August 1st, 2016 is ''TrackingToolsProject 2015-09-23 2.30pm.ttp''.
[[Image:OpeningProject.PNG|800px]]
You should notice that the cameras shown in main project scree arrange themselves like out camera configuration once the project has been opened. Now the constellations need to be loaded. This can be done by going to ''File->Open'' and another pop up window will open. Navigate back to ''D:\Optitrack_Configuration'' (It should open to this directory by default) and select the most recently dated set of RADA trackables. They are named like ''RADA_entireSystem_M_D_YYYY.tra''. The most recent one as of August 1st, 2016 is ''RADA_entireSystem_7_8_2016.tra''.
[[Image:Opening_trackables.PNG|800px]]
Once the project and trackless are open the cameras should appear in their constellation (square) and there should be two constellations under ''Project Explorer->Trackables''. One Named UAV for the pendulum and one named ERIS for the ground vehicle. In order to get additional information about each constellation left click on the the name of the desired trackable.
[[Image:SelectingUAV.PNG|800px]]
Once a trackable is selected more information about it is available in the ''Trackables'' Tab on the right side of the screen. For the current position and orientation look at the ''Real-Time Info'' sub-tab. This gives the orientation in the wrong order for how we currently use the Euler angles. When two or three of the angles are near zero you can switch yaw and pitch to get roughly the correct orientation.
[[Image:Uav_realTimeInfo.PNG|800px]]
Now we need check to make sure the system is zeroed.
1. Hold RADA so that the front of the ground robot (ERIS is facing the wall with the white boards (east)). The front side of Eris is labeled. If it isn't it is the side opposite of the switches and the side with the trackable constellation on it.
2. Make sure that the motor with the red motor mount is also facing the wall with the white boards.
3. Make sure the quad system is aligned along Eris Axis by standing behind the system and seeing if you can use the pole to block mounting bolts of the front propeller motor mount when looking at the pole while facing the east wall.
4. While holding the pendulum approximately vertical see if the camera system reads zeros for the pendulum (UAV) pitch and roll (yaw and roll in ''Real-Time Info''). If yaw is off by a few degrees that is fine.
5. Compare the yaw of the UAV to that of ERIS (Remember this is pitch in ''Real-Time Info''). If they are both near zero and with in a few degrees and the pendulum's pitch/roll were also near zero then you are ready to use the camera system. Otherwise go to the next step.
6. You need to zero the pendulum.
- Align ERIS so it is near zero yaw first (eye ball it).
- Get a level and a friend. Have your friend use a level to ensure that the pendulum is level in both directs and hold it there.
- With the UAV constellation selected go to the ''Orientation'' tab (next to ''Real-Time Info'' tab) and click on ''Reset To Current Orientation button''
- Now your friend can set the pendulum down and you can zero ERIS the same way.
7. Save the new trackable orientation by going to ''File->Save Trakables...'' and save a file using the same naming conventions as the trackable file you opened earlier except use the current data so you don't have to re-zero the system the next time you test.
[[Image:Uav_ResetOrientation.PNG|800px]]
=== Building Software ===
The development environment for running RADA is hosted on CO3050-11, a Linux Red Hat environment. This computer has a local ucart user name that you should use. The password isn't put here for security reasons. In order to ensure that the RADA software is setup correctly for the test you want to run. To do this you will need to open the main.cpp and logger.cpp files and make sure all of the compile time macros you want are defined correctly. All of the c++ files you should need to edit are in the directory ''~/Desktop/rada_research_project/ErisResearchCode/CppProjects/MainProgram_PacketLoss/src/Korebot'' Below is a compiler macro options for main.cpp:
-'''H2ctrl''' : This will cause the system to enter H2 controller mode where the whole RADA system is controlled by an H2 controller.
-'''ssTracking''' : H2ctrl must also be defined for this macro to do anything. This macro will has the system to be controlled by a tracking H2 controller.
-'''ssMotors''' : H2ctrl must also be defined for this macro to do anything. This macro will has the system to be controlled by an H2 contorller that contains propeller states. This also cause the system to "Dance."
-'''ssDrop''' : Cause the system to go into packet drop controller mode. This mode allows controllers designed for lossy networks to be tested. Based off of other definitions how lossy the network is can be simulated. If nothing else is defined this controller becomes basically a H2 controller.
-'''drop10''' : Will put the packet drop mode into 10% loss mode and use a controller designed for 10% loss.
-'''drop30''' : Will put the packet drop mode into 30% loss mode and use a controller designed for 30% loss.
-'''drop50''' : Will put the packet drop mode into 50% loss mode and use a controller designed for 50% loss.
-'''mot50''' : This macro over-rides all other macros. If this is turned on the wheels will not run and the propllers will be run at 50% command. This is used for measuring the effective battery voltage seen by the ESCs. This is always run after a test.
-'''RADAlqi''' : This macro will cause the system to use an LQI controller on the whole system. The linear velocity states are calculated with no filter and the angular velocity states are calculated with filters.
-'''RADAlqi_est''' : This macro will cause the system to use an LQI controller on the whole system. A traditional estimator is used to estimate the states.
-'''rada_lqg''' : This macro will cause the entire system to be controlled by a LQG controller/estimator system.
-'''rada_split_lqg''' : This macro will cause the pendulum and ground robot to be controlled by their own LQG systems.
-'''rada_split_lqg_ol''' : This macro will cause the pendulum to be controlled by an LQG controller, the yaw of the ground robot to be controlled by a PID controller, and the ground robot linear velocities to be controlled with open-loop commands.
-'''yaw_off''' : This macro will cause the yaw control to be disabled on some controllers.
*'''accR''' : This macro will cause the PID linear velocity controllers to be given ramps to acclerate from one velocity to another instead of steps.
-'''posRamp''' : This macro will cause the linear velocities of RADA to be controlled by position PIDs with ramp reference instead of velocity commands.
-If no controller selection is made all controllers revert to PID controllers
All of these macros can be defined simply by uncommenting the corresponding define statement in main.cpp. The macros in the logger.cpp can be seen below:
-'''ssDrop''' : This macro puts the logger into packed drop controller mode and logs the correct values for the packet drop controllers.
-'''RADAlqi''' : This macro puts the logger into full system LQI controller logging mode.
-'''RADAlqi_est''' : This macro puts the logger into full system LQI controller plus estimator logging mode.
-'''rada_lqg''' : This puts the logger into full system LQG controller logging mode.
-'''rada_split_lqg''' : This macro causes the logger to log data about the subsystem LQG controllers.
-'''rada_split_lqg_ol''' : This cause the system to log data about the pendulum LQG system and the open-loop linear velocity commands.
-'''H2ctrl''' : This macro causes the logger to log data about the full system H2 controllers.
-If no logging mode is selected then the logger will default to logging PID data.
Because the system only calculates controllers for one set of controllers it is important to ensure that the logger is in the correct mode based off of what is defined in main.cpp. As of August 1st, 2016 the defines in main.cpp are not seen in logger.cpp.
Finally in a command prompt navigate to the driectroy: ''~/Desktop/rada_research_project/ErisResearchCode/CppProjects/MainProgram_PacketLoss''
Here just type: ''make''. The code will compile for your desired mode. For setting up a new development directory see [http://wikis.ece.iastate.edu/robotic-agriculture-data-acquisition/index.php/Setting_up_a_new_development_environment Setting up a new development environment] from the RADA senior Design wiki.
[[Image:ComplingRADACode.png|800px]]
The complied executable code ends up in ''/home/shared/MainProject''. The ''/home/shared'' directory is setup as a network file share (NFS).
[[Image:ErisCompliedCode-config.png|800px]]
This service needs to be restarted when CO3050-11 is restarted. [http://wikis.ece.iastate.edu/robotic-agriculture-data-acquisition/index.php/Configuring_NFS_shares_for_the_robot Configure NFS shares for the robot] from the RADA Senior Design wiki. Be sure to use the new Linux install command in step six. Though I have fond that even on a good strt the ''[ok]'' messages will still print.
=== Turing on RADA ===
Turing on Eris is fairly simple. Each system has its own battery. There is one for the wheels that plugs in at the front of Eris (opposite side of the swiches), one for the electronics in the back of Eris (in between the switches), and one for the propellers that goes on top of Eris.
[[Image:ErisOnPhoto.jpg|800px]]
The wheel battery is normally 1600 mAh 2-cell Lipo but any 2-cell Lipo will work. The wheels are turned on by flipping the silver switch so the top points away from the system. The electronics normally use a 2600 mAh 2-cell Lipo. The electronics are turned on by flipping the green switch away from the system. It is important that you only the WIFI adapter or Ethernet plugged in at the same time or VRPN my listen to the camera data broadcast over both connects which could cause problems. The propeller system is powered via a 2600 mAh 4-cell Lipo that connects to a power cable at the base of the pendulum. There is a switch to turn on the power to the propellers system. You will know it is on when the 1 on the switch is flush with the switch housing instead of sticking out. It takes about 30 seconds to a minute for Eris to boot up and start the networking connections. When the WIFI is plugged in you will know it is ready when a blue light turns on, on the module.
=== Connecting to RADA ===
RADA is controlled through an SSH connection. in a commands prompt, not the one you compile the code from so that you can recompile for different setup with out needing to close the connection. If you are using a WIFI connect use the command ''ssh root@192.168.0.53''. If you are connected to Eris through a LAN connaction use the command ''ssh root@192.168.0.54''. If the connection goes though you should be proped for a password.
The password is ''rootme''.
[[Image:Ssh2Eris.png|800px]]
It is important to close the SSH connection before turning off Eris because the terminal you are using will hang up if you don't. You can close the connection by using the command ''exit''.
[[Image:ClosingSSH.png|800px]]
== Testing RADA ==
Now that you are connected to Eris you can run tests. The testing is started by a few different methods.
=== Running the first test after power up ===
For the firs test after powering on Eris a few additional steps need to be completed in order to test the system. The FPGA motor controller needs to be programmed and Eris needs to connect the the NFS server running on CO3050-11. This is accomplished by running ''1_co3050-11.sh'', this shell scrip will setup the NFS, load the bit file into the FPGA configuration memory. Then it retrieves the executable file from the NFS server ''/mnt/nfs/MainProject and runs the executable. Once the user exits the executable the log file produces is copied from the ''~/Logs/YYYY_MM_DD_Day'' directory on Eris to ''/home/shared/MainProject/Logs/YYYY_MM_DD_Day'' on CO3050-11. When the folder for the current Eris date doesn't exist it creates this directory in CO3050-11 and then removes the directory and log file from Eris. You may see an warning that when coping the log file Eris couldn't maintain the file permisiion settings. This is normal as Eris doesn't have the same access to the NSF server as it has to its own files. This Date stamp uses date on Eris which is currently in June of 2008 as of August 2nd, 2016.
Before starting the test it is best to have someone spotting the pendulum a holding it near vertical so that the pendulum doesn't have issues when entering a control mode.'''<span style="color:red"> Always run ensure the pendulum is spotted by a second person when testing so you don't hurt yourself, others in the lab, or the RADA system.</span>''' Once you spotter is ready run the shell scrip by= using the command ''./1_co3050-11.sh'' in the terminal with the open SSH connection to Eris from the home, ''/root'', directory of Eris. When you run this script there will be a bunch of information printed out about the PIC bus and loading the bit file to configure the FPGA, you will know that RADA is ready for the test when it asks you to select a running mode. See the Testing Modes section below. This script can take a while to complete so beyond the first test after start up you don't need to run this script. See the Section about Running additional tests below.
[[Image:StartingRADA initial.png|800px]]
=== Testing Modes ===
The RADA system has three testing modes: Robot Control Mode, Tuning Mode, and Box Step Mode. Additionally you can exit the execution at any time by pressing the ''Esc'' key. Once the terminal asks you to chose a mode you can use the following commands to enter the desired mode with a three second delay or exit the program. You can also use these commands to switch between the modes.
-''v'' : Enters the pendulum PID tuning mode, this will only really work when using PIDs to control the pendulum.
-''b'' : Enter Robot control mode, in this mode you can drive the robot around and the pendulum will try to stay vertical. This is the main mode used for testing the whole RADA system.
-''n'' : Enters box step mode, where the pendulum will change its desired pitch and roll angles every 20 seconds and move in a box shape.
-''Esc'' : By hitting the escape key the program will exit the program.
You will almost always want to run Robot Control Mode as the other modes are legacy modes from when we initially built and tested RADA and only works with the pendulum PID controllers. There are also a few utility commands that can be used in all modes.
-''2'' : Resets I composts of the Pitch/Roll PIDs and only the PIDs.
-''m'' : Adds a marker to the Log file incase odd things happen somewhere. This just increments a counter so if you use it look for changes in the marker value.
==== Robot Control Model ====
In Robot control mode you can control the motion of Eris. For PID control of Eris or 1D state feedback system the directional commands command Eris body velocity were for full system and Eris system state feedback controllers control the global velocity. All of these keys only need to be pressed not held down.
-''w'' : Moves Eris forward (+x) at some velocity depending on the controller.
-''s'' : Moves Eris in reverse (-x) at some velocity depending on the controller.
-''d'' : Moves Eris in right (+y) at some velocity depending on the controller.
-''a'' : Moves Eris in left (-y) at some velocity depending on the controller.
-''p'' : Stops the motion of Eris (Set all velocity set points to zero). I.e. if you hit ''w'' then hit ''s'' then Eris will be moving in reverse.
-''y'' : Moves Eris forward and to the right (+x/+y) simultaneously at some velocity depending on the controller.
-''t'' : Moves Eris forward and to the left (+x/-y) simultaneously at some velocity depending on the controller.
-''i'' : Moves Eris reverse and to the right (-x/+y) simultaneously at some velocity depending on the controller.
-''y'' : Moves Eris reverse and to the left (-x/-y) simultaneously at some velocity depending on the controller.
-''e'' : Rotate Eris clockwise (+yaw) at some angular rate. This only worked when RADA used the closed-loop FPGA control of the wheels. There is currently no controllers that use this command.
-''q'' : Rotate Eris counter-clockwise (-yaw) at some angular rate. This only worked when RADA used the closed-loop FPGA control of the wheels. There is currently no controllers that use this command.
-''<'' : Increment Eris' desired heading 45 degrees counter-clockwise (-yaw).
-''>'' : Increment Eris' desired heading 45 degrees clockwise (+yaw).
-''7'' : Increments the pitch set point (+pitch).
-''4'' : Decrements the pitch set point (-pitch).
-''8'' : Increments the roll set point (+roll).
-''5'' : Decrements the roll set point (-roll).
==== Tuning Mode ====
Tuning mode allows you to tune the PID controllers for both pitch and roll. The UI commands here are also available in Box Step Mode.
-''1'' : Tune the Pitch PID.
-''3'' : Tune the Roll PID.
-''7'' : Increase proportional gain of PID being tuned.
-''4'' : Decrease proportional gain of PID being tuned.
-''8'' : Increase integral gain of PID being tuned.
-''5'' : Decrease integral gain of PID being tuned.
-''9'' : Increase derivative gain of PID being tuned.
-''6'' : Decrease derivative gain of PID being tuned.
-''i'' : Increase set point of PID being tuned.
-''k'' : Decrease set point of PID being tuned.
-''o'' : Increase integral windup term of PID being tuned. (Not used)
-''l'' : Decrease integral windup term of PID being tuned. (Not used)
==== Box Step Mode ====
Box set mode will automatically change the set points of the pendulum every 20 seconds. The case statement for this mode can be changed for 1D and 2D step modes. This mode allows the user to use he same commands as Tuning Mode.
=== Running additional Tests ===
Once you have run one test with Eris on it is unnecessary to configure the FPGA or connect to the NFS server again. This is what took much of the time in the initial setup. This is what the script ''3_stat_eris.sh'' was developed for. It does everything that ''1_co3050-11.sh'' does but without reprogramming the FPGA or reconnecting to the NFS server. As a result it is ready to test much quicker.
Before starting the test it is best to have someone spotting the pendulum a holding it near vertical so that the pendulum doesn't have issues when entering a control mode.'''<span style="color:red"> Always run ensure the pendulum is spotted by a second person when testing so you don't hurt yourself, others in the lab, or the RADA system.</span>''' Once you spotter is ready run the shell scrip by= using the command ''./3_start_eris.sh'' in the terminal with the open SSH connection to Eris from the home, ''/root'', directory of Eris.
[[Image:StartingRADA2nd.png|800px]]
=== Locating and retrieving log files ===
Once you are done with a test that you want to compare to the model you should retrieve the log file right away so you don't mix it up with other test. On CO3050-11 go to the dircetory ''/home/shared/MainProject/Logs'' using the file browser (you can do this in a terminal but it is easier from the file explorer). Once there, look for the folder that has been modified most recently as Eris date is normally out of sync with its date and time. Then look for the newest log file. Log files are named like ''log(hh.mm.ss).txt'' (ex. log(13.04.51).txt). This naming convention works well to ensure that no log file is over written but it isn't useful of describing what the test was of or for. Copy this log to the Desktop or to a USB drive and rename it. A good method is to name the file something like ''RADA_ctrl_otherNote#.txt'', where Describes what system you tested (ex. RADA, RADA1D, PEN1D, PEN2D), what typ of controller was used, other notes and then a number if this is a repeat of another test. This is much more useful when looking back at these logs later on. Before transferring the log file for processing you should record the wheel and propeller battery voltages in the header of the log file. The log file format is both human readable and can be parsed by MATALB. It was designed by the first RADA Senior Design Team and more information about the log files can be found [http://wikis.ece.iastate.edu/robotic-agriculture-data-acquisition/index.php/Data_Analysis_Tool here.] See he section below on measuring battery voltage below in order to get the best measurements for simulation of RADA.
=== Measuring battery voltages ===
The last thing that you need to do before simulating an experiment of the RADA platform is record the battery voltages for both the wheels and propellers. The wheel battery can be measured unloaded as there isn't large line losses between the battery and the H-bridges. The propeller battery voltage needs to be measured under load because the power cord running up the pendulum has significant line losses at the currents the propellers draw when in use. The battery voltages can be recorded in the log file for the test. Open the log file for the test you just completed (Use KWrite for Linux machines or Notepad++ for Windows machines). The first few lines of the log is the headder. It should look like this:
#Constants pitch_P pitch_I pitch_D
#PIDValues 48000 18000 21000
#Constants roll_P roll_I roll_D
#PIDValues 48000 18000 21000
#Battery Vquad Vwheels
#Voltage
Follow the procedure for measuring the voltage of each battery and then record the voltage under the corresponding battery. Then save the log file and close out of your text editor and the test will be ready for processing. Recoding the battery voltages in this way makes it much easier to find if you need the value latter. The final log file header should look like this once you are done
#Constants pitch_P pitch_I pitch_D
#PIDValues 48000 18000 21000
#Constants roll_P roll_I roll_D
#PIDValues 48000 18000 21000
#Battery Vquad Vwheels
#Voltage 14.44 8.257
==== Wheel Battery ====
1. After test disconnect wheel battery from the system.
2. Measure voltage of battery using multimeter.
[[Image:MeasureVwheel.jpg|800px]]
You can use the plug used for charging the 2-cell Lipos but make sure to connect the plug to the multimeter before connecting the battery and disconnect the battery before disconnecting the plug from the mulitmeter. It is generally the best practice to give the multimeter a few minutes to allow for the voltage measurement to stabilize as the battery measurement tends to be a little low right after the test.
==== Quad Battery ====
1. Setup code to run all four propellers at 50% throttle, uncomment the definition of ''mot50'' in main.cpp and compile the project.
2. Power off propellers by turning off the switch to the ESCs.
3. Connect multimeter to measure the voltage across one of the ESCs. This is done by using the power splitter cord.
-Connect one of the female XT60 connectors on the splitter to a male XT60 connector to banana connector cable.
-The banana connector connect to the hand held multimeter. The multimeter should be set to the 20VDC measurement setting.
-Next unplug one the ESCs' power connection.
-reconnect the ESC to power through the two remain connectors on the spliter cable.
4. Power on the propellers.
5. Run the system at 50% throttle and measure the steady-state voltage during the test.
== Post processing and Simulation ==
=== Using the MATLAB data parsing tool ===
=== Adding additional data for simulations ===
=== Setting up the MATLAB workspace for simulation ===
=== Running simulations and storing results ===
=== Plotting results ===
be3dd8038f487120aa0034bbeefaad08af98a318
256
251
2016-08-02T20:49:37Z
Pfuhing
5
wikitext
text/x-wiki
This page will take you though setting up and testing RADA, retrieving the log file and other necessary data to run a simulation of that test and processing the data in MATLAB. Then actually running the simulation of RADA in Simulink.
== Setting Up a RADA Test ==
Testing RADA is not overly difficult once you get the hang of the steps to setup RADA. The following steps may seem like a long process to go from starting the testing process to having completed simulation and plotting of the test results but this whole test procedure (with the exception of battery charging) can be completed in about 15-20 minutes. These steps are meant to be as detailed as possible in order to help new users of RADA to get up and running as quickly as possible.
'''<span style="color:red">NOTE: Always run RADA with at least 2 people!</span>''' The pendulum arm can crash into the ground if the network starts to drop packets and one person cannot give commands to RADA and spot the pendulum. This is a safety issue for both you and the RADA platform.
=== Charging batteries ===
The lab currently uses mostly Hyperion batteries. We charge our batteries with a Hyperion EOS 1420i Net3 battery charger. For some general information about how to use this charger see [https://www.youtube.com/watch?v=-ox3EpzvsJ8 this video.]. In the lab we power this charger using the old Kepco Power supplu because it is the only power supply that we have that can supply enough current. Make sure that the power supply is set to an output voltage between 10.5V-29V.
{| class="wikitable" style="text-align:center"
|-
| [[Image:ChargerPowerSupplyOff.JPG|400px]]
| [[Image:ChargerPowerSuplyOn.JPG|400px]]
|-
| Kepco Power Supply off.
| Kepco Power Supply on with correct voltage supply range.
|}
While the YouTube video linked above should explain how to use the charger. Currently three different Lithium polymer batteries (Lipo): 1600 mAh 2-cell Lipo for the wheels, 2600 mAh 2-cell Lipo for the electronics of Eris, and a 2600 mAh 4-cell Lipo. The 1600 mAh 2-cell Lipo can be charged using memory slot 2 of the charger. The 2600 mAh 2-cell Lipos can be charged using memory slot 3 for fast charging and memory slot 4 for slower charging (use this if the battery gets run really low for 10-20 minutes then switch to fast charging). The 2600 mAh 4-cell Lipo can be charged using memory slot 8. The 1600 mAh 2-cell and 2600 mAr 4-cell generally charge in 10-20 minutes apiece while I generally fine it takes the 2600 mAh 2-cell up to 70 minutes to charge fully.
=== Setting up the camera system ===
The camera system is run on the windows computer CO3050-07. You can log into this computer using a local microcart username and password which is not posted here for security reasons but any one who works in the lab should know it. Once logged in look for Tracking Tools in the start menu or look for the shortcut shown below:
[[Image:TrackingTools_shortcut.PNG|thumb|center|Tracking Tools shortcut]]
Once the program opens the screen should look something like this:
[[Image:NewTrackingTools.PNG|800px]]
In the Tracking Tools Quick Start pop up menu select Open Existing Project and then navigate to ''D:\Optitrack_Configuration'' (It should open to this directory by default) and select the most recent Tracking Tools project. It should be named like ''TrackingToolsProject YYYY-MM-DD timeStamp.ttp''. This is normally the most recently edited file when sorting by data modified. The most recent one as of August 1st, 2016 is ''TrackingToolsProject 2015-09-23 2.30pm.ttp''.
[[Image:OpeningProject.PNG|800px]]
You should notice that the cameras shown in main project scree arrange themselves like out camera configuration once the project has been opened. Now the constellations need to be loaded. This can be done by going to ''File->Open'' and another pop up window will open. Navigate back to ''D:\Optitrack_Configuration'' (It should open to this directory by default) and select the most recently dated set of RADA trackables. They are named like ''RADA_entireSystem_M_D_YYYY.tra''. The most recent one as of August 1st, 2016 is ''RADA_entireSystem_7_8_2016.tra''.
[[Image:Opening_trackables.PNG|800px]]
Once the project and trackless are open the cameras should appear in their constellation (square) and there should be two constellations under ''Project Explorer->Trackables''. One Named UAV for the pendulum and one named ERIS for the ground vehicle. In order to get additional information about each constellation left click on the the name of the desired trackable.
[[Image:SelectingUAV.PNG|800px]]
Once a trackable is selected more information about it is available in the ''Trackables'' Tab on the right side of the screen. For the current position and orientation look at the ''Real-Time Info'' sub-tab. This gives the orientation in the wrong order for how we currently use the Euler angles. When two or three of the angles are near zero you can switch yaw and pitch to get roughly the correct orientation.
[[Image:Uav_realTimeInfo.PNG|800px]]
Now we need check to make sure the system is zeroed.
1. Hold RADA so that the front of the ground robot (ERIS is facing the wall with the white boards (east)). The front side of Eris is labeled. If it isn't it is the side opposite of the switches and the side with the trackable constellation on it.
2. Make sure that the motor with the red motor mount is also facing the wall with the white boards.
3. Make sure the quad system is aligned along Eris Axis by standing behind the system and seeing if you can use the pole to block mounting bolts of the front propeller motor mount when looking at the pole while facing the east wall.
4. While holding the pendulum approximately vertical see if the camera system reads zeros for the pendulum (UAV) pitch and roll (yaw and roll in ''Real-Time Info''). If yaw is off by a few degrees that is fine.
5. Compare the yaw of the UAV to that of ERIS (Remember this is pitch in ''Real-Time Info''). If they are both near zero and with in a few degrees and the pendulum's pitch/roll were also near zero then you are ready to use the camera system. Otherwise go to the next step.
6. You need to zero the pendulum.
- Align ERIS so it is near zero yaw first (eye ball it).
- Get a level and a friend. Have your friend use a level to ensure that the pendulum is level in both directs and hold it there.
- With the UAV constellation selected go to the ''Orientation'' tab (next to ''Real-Time Info'' tab) and click on ''Reset To Current Orientation button''
- Now your friend can set the pendulum down and you can zero ERIS the same way.
7. Save the new trackable orientation by going to ''File->Save Trakables...'' and save a file using the same naming conventions as the trackable file you opened earlier except use the current data so you don't have to re-zero the system the next time you test.
[[Image:Uav_ResetOrientation.PNG|800px]]
=== Building Software ===
The development environment for running RADA is hosted on CO3050-11, a Linux Red Hat environment. This computer has a local ucart user name that you should use. The password isn't put here for security reasons. In order to ensure that the RADA software is setup correctly for the test you want to run. To do this you will need to open the main.cpp and logger.cpp files and make sure all of the compile time macros you want are defined correctly. All of the c++ files you should need to edit are in the directory ''~/Desktop/rada_research_project/ErisResearchCode/CppProjects/MainProgram_PacketLoss/src/Korebot'' Below is a compiler macro options for main.cpp:
-'''H2ctrl''' : This will cause the system to enter H2 controller mode where the whole RADA system is controlled by an H2 controller.
-'''ssTracking''' : H2ctrl must also be defined for this macro to do anything. This macro will has the system to be controlled by a tracking H2 controller.
-'''ssMotors''' : H2ctrl must also be defined for this macro to do anything. This macro will has the system to be controlled by an H2 contorller that contains propeller states. This also cause the system to "Dance."
-'''ssDrop''' : Cause the system to go into packet drop controller mode. This mode allows controllers designed for lossy networks to be tested. Based off of other definitions how lossy the network is can be simulated. If nothing else is defined this controller becomes basically a H2 controller.
-'''drop10''' : Will put the packet drop mode into 10% loss mode and use a controller designed for 10% loss.
-'''drop30''' : Will put the packet drop mode into 30% loss mode and use a controller designed for 30% loss.
-'''drop50''' : Will put the packet drop mode into 50% loss mode and use a controller designed for 50% loss.
-'''mot50''' : This macro over-rides all other macros. If this is turned on the wheels will not run and the propllers will be run at 50% command. This is used for measuring the effective battery voltage seen by the ESCs. This is always run after a test.
-'''RADAlqi''' : This macro will cause the system to use an LQI controller on the whole system. The linear velocity states are calculated with no filter and the angular velocity states are calculated with filters.
-'''RADAlqi_est''' : This macro will cause the system to use an LQI controller on the whole system. A traditional estimator is used to estimate the states.
-'''rada_lqg''' : This macro will cause the entire system to be controlled by a LQG controller/estimator system.
-'''rada_split_lqg''' : This macro will cause the pendulum and ground robot to be controlled by their own LQG systems.
-'''rada_split_lqg_ol''' : This macro will cause the pendulum to be controlled by an LQG controller, the yaw of the ground robot to be controlled by a PID controller, and the ground robot linear velocities to be controlled with open-loop commands.
-'''yaw_off''' : This macro will cause the yaw control to be disabled on some controllers.
*'''accR''' : This macro will cause the PID linear velocity controllers to be given ramps to acclerate from one velocity to another instead of steps.
-'''posRamp''' : This macro will cause the linear velocities of RADA to be controlled by position PIDs with ramp reference instead of velocity commands.
-If no controller selection is made all controllers revert to PID controllers
All of these macros can be defined simply by uncommenting the corresponding define statement in main.cpp. The macros in the logger.cpp can be seen below:
-'''ssDrop''' : This macro puts the logger into packed drop controller mode and logs the correct values for the packet drop controllers.
-'''RADAlqi''' : This macro puts the logger into full system LQI controller logging mode.
-'''RADAlqi_est''' : This macro puts the logger into full system LQI controller plus estimator logging mode.
-'''rada_lqg''' : This puts the logger into full system LQG controller logging mode.
-'''rada_split_lqg''' : This macro causes the logger to log data about the subsystem LQG controllers.
-'''rada_split_lqg_ol''' : This cause the system to log data about the pendulum LQG system and the open-loop linear velocity commands.
-'''H2ctrl''' : This macro causes the logger to log data about the full system H2 controllers.
-If no logging mode is selected then the logger will default to logging PID data.
Because the system only calculates controllers for one set of controllers it is important to ensure that the logger is in the correct mode based off of what is defined in main.cpp. As of August 1st, 2016 the defines in main.cpp are not seen in logger.cpp.
Finally in a command prompt navigate to the driectroy: ''~/Desktop/rada_research_project/ErisResearchCode/CppProjects/MainProgram_PacketLoss''
Here just type: ''make''. The code will compile for your desired mode. For setting up a new development directory see [http://wikis.ece.iastate.edu/robotic-agriculture-data-acquisition/index.php/Setting_up_a_new_development_environment Setting up a new development environment] from the RADA senior Design wiki.
[[Image:ComplingRADACode.png|800px]]
The complied executable code ends up in ''/home/shared/MainProject''. The ''/home/shared'' directory is setup as a network file share (NFS).
[[Image:ErisCompliedCode-config.png|800px]]
This service needs to be restarted when CO3050-11 is restarted. [http://wikis.ece.iastate.edu/robotic-agriculture-data-acquisition/index.php/Configuring_NFS_shares_for_the_robot Configure NFS shares for the robot] from the RADA Senior Design wiki. Be sure to use the new Linux install command in step six. Though I have fond that even on a good strt the ''[ok]'' messages will still print.
=== Turing on RADA ===
Turing on Eris is fairly simple. Each system has its own battery. There is one for the wheels that plugs in at the front of Eris (opposite side of the swiches), one for the electronics in the back of Eris (in between the switches), and one for the propellers that goes on top of Eris.
[[Image:ErisOnPhoto.jpg|800px]]
The wheel battery is normally 1600 mAh 2-cell Lipo but any 2-cell Lipo will work. The wheels are turned on by flipping the silver switch so the top points away from the system. The electronics normally use a 2600 mAh 2-cell Lipo. The electronics are turned on by flipping the green switch away from the system. It is important that you only the WIFI adapter or Ethernet plugged in at the same time or VRPN my listen to the camera data broadcast over both connects which could cause problems. The propeller system is powered via a 2600 mAh 4-cell Lipo that connects to a power cable at the base of the pendulum. There is a switch to turn on the power to the propellers system. You will know it is on when the 1 on the switch is flush with the switch housing instead of sticking out. It takes about 30 seconds to a minute for Eris to boot up and start the networking connections. When the WIFI is plugged in you will know it is ready when a blue light turns on, on the module.
=== Connecting to RADA ===
RADA is controlled through an SSH connection. in a commands prompt, not the one you compile the code from so that you can recompile for different setup with out needing to close the connection. If you are using a WIFI connect use the command ''ssh root@192.168.0.53''. If you are connected to Eris through a LAN connaction use the command ''ssh root@192.168.0.54''. If the connection goes though you should be proped for a password.
The password is ''rootme''.
[[Image:Ssh2Eris.png|800px]]
It is important to close the SSH connection before turning off Eris because the terminal you are using will hang up if you don't. You can close the connection by using the command ''exit''.
[[Image:ClosingSSH.png|800px]]
== Testing RADA ==
Now that you are connected to Eris you can run tests. The testing is started by a few different methods.
=== Running the first test after power up ===
For the firs test after powering on Eris a few additional steps need to be completed in order to test the system. The FPGA motor controller needs to be programmed and Eris needs to connect the the NFS server running on CO3050-11. This is accomplished by running ''1_co3050-11.sh'', this shell scrip will setup the NFS, load the bit file into the FPGA configuration memory. Then it retrieves the executable file from the NFS server ''/mnt/nfs/MainProject and runs the executable. Once the user exits the executable the log file produces is copied from the ''~/Logs/YYYY_MM_DD_Day'' directory on Eris to ''/home/shared/MainProject/Logs/YYYY_MM_DD_Day'' on CO3050-11. When the folder for the current Eris date doesn't exist it creates this directory in CO3050-11 and then removes the directory and log file from Eris. You may see an warning that when coping the log file Eris couldn't maintain the file permisiion settings. This is normal as Eris doesn't have the same access to the NSF server as it has to its own files. This Date stamp uses date on Eris which is currently in June of 2008 as of August 2nd, 2016.
Before starting the test it is best to have someone spotting the pendulum a holding it near vertical so that the pendulum doesn't have issues when entering a control mode.'''<span style="color:red"> Always run ensure the pendulum is spotted by a second person when testing so you don't hurt yourself, others in the lab, or the RADA system.</span>''' Once you spotter is ready run the shell scrip by= using the command ''./1_co3050-11.sh'' in the terminal with the open SSH connection to Eris from the home, ''/root'', directory of Eris. When you run this script there will be a bunch of information printed out about the PIC bus and loading the bit file to configure the FPGA, you will know that RADA is ready for the test when it asks you to select a running mode. See the Testing Modes section below. This script can take a while to complete so beyond the first test after start up you don't need to run this script. See the Section about Running additional tests below.
[[Image:StartingRADA initial.png|800px]]
=== Testing Modes ===
The RADA system has three testing modes: Robot Control Mode, Tuning Mode, and Box Step Mode. Additionally you can exit the execution at any time by pressing the ''Esc'' key. Once the terminal asks you to chose a mode you can use the following commands to enter the desired mode with a three second delay or exit the program. You can also use these commands to switch between the modes.
-''v'' : Enters the pendulum PID tuning mode, this will only really work when using PIDs to control the pendulum.
-''b'' : Enter Robot control mode, in this mode you can drive the robot around and the pendulum will try to stay vertical. This is the main mode used for testing the whole RADA system.
-''n'' : Enters box step mode, where the pendulum will change its desired pitch and roll angles every 20 seconds and move in a box shape.
-''Esc'' : By hitting the escape key the program will exit the program.
You will almost always want to run Robot Control Mode as the other modes are legacy modes from when we initially built and tested RADA and only works with the pendulum PID controllers. There are also a few utility commands that can be used in all modes.
-''2'' : Resets I composts of the Pitch/Roll PIDs and only the PIDs.
-''m'' : Adds a marker to the Log file incase odd things happen somewhere. This just increments a counter so if you use it look for changes in the marker value.
==== Robot Control Model ====
In Robot control mode you can control the motion of Eris. For PID control of Eris or 1D state feedback system the directional commands command Eris body velocity were for full system and Eris system state feedback controllers control the global velocity. All of these keys only need to be pressed not held down.
-''w'' : Moves Eris forward (+x) at some velocity depending on the controller.
-''s'' : Moves Eris in reverse (-x) at some velocity depending on the controller.
-''d'' : Moves Eris in right (+y) at some velocity depending on the controller.
-''a'' : Moves Eris in left (-y) at some velocity depending on the controller.
-''p'' : Stops the motion of Eris (Set all velocity set points to zero). I.e. if you hit ''w'' then hit ''s'' then Eris will be moving in reverse.
-''y'' : Moves Eris forward and to the right (+x/+y) simultaneously at some velocity depending on the controller.
-''t'' : Moves Eris forward and to the left (+x/-y) simultaneously at some velocity depending on the controller.
-''i'' : Moves Eris reverse and to the right (-x/+y) simultaneously at some velocity depending on the controller.
-''y'' : Moves Eris reverse and to the left (-x/-y) simultaneously at some velocity depending on the controller.
-''e'' : Rotate Eris clockwise (+yaw) at some angular rate. This only worked when RADA used the closed-loop FPGA control of the wheels. There is currently no controllers that use this command.
-''q'' : Rotate Eris counter-clockwise (-yaw) at some angular rate. This only worked when RADA used the closed-loop FPGA control of the wheels. There is currently no controllers that use this command.
-''<'' : Increment Eris' desired heading 45 degrees counter-clockwise (-yaw).
-''>'' : Increment Eris' desired heading 45 degrees clockwise (+yaw).
-''7'' : Increments the pitch set point (+pitch).
-''4'' : Decrements the pitch set point (-pitch).
-''8'' : Increments the roll set point (+roll).
-''5'' : Decrements the roll set point (-roll).
==== Tuning Mode ====
Tuning mode allows you to tune the PID controllers for both pitch and roll. The UI commands here are also available in Box Step Mode.
-''1'' : Tune the Pitch PID.
-''3'' : Tune the Roll PID.
-''7'' : Increase proportional gain of PID being tuned.
-''4'' : Decrease proportional gain of PID being tuned.
-''8'' : Increase integral gain of PID being tuned.
-''5'' : Decrease integral gain of PID being tuned.
-''9'' : Increase derivative gain of PID being tuned.
-''6'' : Decrease derivative gain of PID being tuned.
-''i'' : Increase set point of PID being tuned.
-''k'' : Decrease set point of PID being tuned.
-''o'' : Increase integral windup term of PID being tuned. (Not used)
-''l'' : Decrease integral windup term of PID being tuned. (Not used)
==== Box Step Mode ====
Box set mode will automatically change the set points of the pendulum every 20 seconds. The case statement for this mode can be changed for 1D and 2D step modes. This mode allows the user to use he same commands as Tuning Mode.
=== Running additional Tests ===
Once you have run one test with Eris on it is unnecessary to configure the FPGA or connect to the NFS server again. This is what took much of the time in the initial setup. This is what the script ''3_stat_eris.sh'' was developed for. It does everything that ''1_co3050-11.sh'' does but without reprogramming the FPGA or reconnecting to the NFS server. As a result it is ready to test much quicker.
Before starting the test it is best to have someone spotting the pendulum a holding it near vertical so that the pendulum doesn't have issues when entering a control mode.'''<span style="color:red"> Always run ensure the pendulum is spotted by a second person when testing so you don't hurt yourself, others in the lab, or the RADA system.</span>''' Once you spotter is ready run the shell scrip by= using the command ''./3_start_eris.sh'' in the terminal with the open SSH connection to Eris from the home, ''/root'', directory of Eris.
[[Image:StartingRADA2nd.png|800px]]
=== Locating and retrieving log files ===
Once you are done with a test that you want to compare to the model you should retrieve the log file right away so you don't mix it up with other test. On CO3050-11 go to the dircetory ''/home/shared/MainProject/Logs'' using the file browser (you can do this in a terminal but it is easier from the file explorer). Once there, look for the folder that has been modified most recently as Eris date is normally out of sync with its date and time. Then look for the newest log file. Log files are named like ''log(hh.mm.ss).txt'' (ex. log(13.04.51).txt). This naming convention works well to ensure that no log file is over written but it isn't useful of describing what the test was of or for. Copy this log to the Desktop or to a USB drive and rename it. A good method is to name the file something like ''RADA_ctrl_otherNote#.txt'', where Describes what system you tested (ex. RADA, RADA1D, PEN1D, PEN2D), what typ of controller was used, other notes and then a number if this is a repeat of another test. This is much more useful when looking back at these logs later on. Before transferring the log file for processing you should record the wheel and propeller battery voltages in the header of the log file. The log file format is both human readable and can be parsed by MATALB. It was designed by the first RADA Senior Design Team and more information about the log files can be found [http://wikis.ece.iastate.edu/robotic-agriculture-data-acquisition/index.php/Data_Analysis_Tool here.] See he section below on measuring battery voltage below in order to get the best measurements for simulation of RADA.
=== Measuring battery voltages ===
The last thing that you need to do before simulating an experiment of the RADA platform is record the battery voltages for both the wheels and propellers. The wheel battery can be measured unloaded as there isn't large line losses between the battery and the H-bridges. The propeller battery voltage needs to be measured under load because the power cord running up the pendulum has significant line losses at the currents the propellers draw when in use. The battery voltages can be recorded in the log file for the test. Open the log file for the test you just completed (Use KWrite for Linux machines or Notepad++ for Windows machines). The first few lines of the log is the headder. It should look like this:
#Constants pitch_P pitch_I pitch_D
#PIDValues 48000 18000 21000
#Constants roll_P roll_I roll_D
#PIDValues 48000 18000 21000
#Battery Vquad Vwheels
#Voltage
Follow the procedure for measuring the voltage of each battery and then record the voltage under the corresponding battery. Then save the log file and close out of your text editor and the test will be ready for processing. Recoding the battery voltages in this way makes it much easier to find if you need the value latter. The final log file header should look like this once you are done
#Constants pitch_P pitch_I pitch_D
#PIDValues 48000 18000 21000
#Constants roll_P roll_I roll_D
#PIDValues 48000 18000 21000
#Battery Vquad Vwheels
#Voltage 14.44 8.257
==== Wheel Battery ====
1. After test disconnect wheel battery from the system.
2. Measure voltage of battery using multimeter.
[[Image:MeasureVwheel.jpg|800px]]
You can use the plug used for charging the 2-cell Lipos but make sure to connect the plug to the multimeter before connecting the battery and disconnect the battery before disconnecting the plug from the mulitmeter. It is generally the best practice to give the multimeter a few minutes to allow for the voltage measurement to stabilize as the battery measurement tends to be a little low right after the test.
==== Quad Battery ====
1. Setup code to run all four propellers at 50% throttle, uncomment the definition of ''mot50'' in main.cpp and compile the project.
2. Power off propellers by turning off the switch to the ESCs.
3. Connect multimeter to measure the voltage across one of the ESCs. This is done by using the power splitter cord.
-Connect one of the female XT60 connectors on the splitter to a male XT60 connector to banana connector cable.
-The banana connector connect to the hand held multimeter. The multimeter should be set to the 20VDC measurement setting.
-Next unplug one the ESCs' power connection.
-reconnect the ESC to power through the two remain connectors on the spliter cable.
4. Power on the propellers.
5. Run the system at 50% throttle and measure the steady-state voltage during the test.
{| class="wikitable" style="text-align:center"
|-
| [[Image:PowerSplitter.jpg|200px]]
| [[Image:QuadMultiCon.jpg |200px]]
| [[Image:QuadMultiSet.JPG |200px]]
| [[Image:QuadMeasESCcon.JPG|200px]]
|-
| Splitter cord.
| Connect splitter to multimeter.
| Settings for multimeter.
| Connecting ESC through splitter.
|}
== Post processing and Simulation ==
=== Using the MATLAB data parsing tool ===
=== Adding additional data for simulations ===
=== Setting up the MATLAB workspace for simulation ===
=== Running simulations and storing results ===
=== Plotting results ===
c043352430020dd172b243862477378e795c082c
257
256
2016-08-02T20:52:31Z
Pfuhing
5
/* Quad Battery */
wikitext
text/x-wiki
This page will take you though setting up and testing RADA, retrieving the log file and other necessary data to run a simulation of that test and processing the data in MATLAB. Then actually running the simulation of RADA in Simulink.
== Setting Up a RADA Test ==
Testing RADA is not overly difficult once you get the hang of the steps to setup RADA. The following steps may seem like a long process to go from starting the testing process to having completed simulation and plotting of the test results but this whole test procedure (with the exception of battery charging) can be completed in about 15-20 minutes. These steps are meant to be as detailed as possible in order to help new users of RADA to get up and running as quickly as possible.
'''<span style="color:red">NOTE: Always run RADA with at least 2 people!</span>''' The pendulum arm can crash into the ground if the network starts to drop packets and one person cannot give commands to RADA and spot the pendulum. This is a safety issue for both you and the RADA platform.
=== Charging batteries ===
The lab currently uses mostly Hyperion batteries. We charge our batteries with a Hyperion EOS 1420i Net3 battery charger. For some general information about how to use this charger see [https://www.youtube.com/watch?v=-ox3EpzvsJ8 this video.]. In the lab we power this charger using the old Kepco Power supplu because it is the only power supply that we have that can supply enough current. Make sure that the power supply is set to an output voltage between 10.5V-29V.
{| class="wikitable" style="text-align:center"
|-
| [[Image:ChargerPowerSupplyOff.JPG|400px]]
| [[Image:ChargerPowerSuplyOn.JPG|400px]]
|-
| Kepco Power Supply off.
| Kepco Power Supply on with correct voltage supply range.
|}
While the YouTube video linked above should explain how to use the charger. Currently three different Lithium polymer batteries (Lipo): 1600 mAh 2-cell Lipo for the wheels, 2600 mAh 2-cell Lipo for the electronics of Eris, and a 2600 mAh 4-cell Lipo. The 1600 mAh 2-cell Lipo can be charged using memory slot 2 of the charger. The 2600 mAh 2-cell Lipos can be charged using memory slot 3 for fast charging and memory slot 4 for slower charging (use this if the battery gets run really low for 10-20 minutes then switch to fast charging). The 2600 mAh 4-cell Lipo can be charged using memory slot 8. The 1600 mAh 2-cell and 2600 mAr 4-cell generally charge in 10-20 minutes apiece while I generally fine it takes the 2600 mAh 2-cell up to 70 minutes to charge fully.
=== Setting up the camera system ===
The camera system is run on the windows computer CO3050-07. You can log into this computer using a local microcart username and password which is not posted here for security reasons but any one who works in the lab should know it. Once logged in look for Tracking Tools in the start menu or look for the shortcut shown below:
[[Image:TrackingTools_shortcut.PNG|thumb|center|Tracking Tools shortcut]]
Once the program opens the screen should look something like this:
[[Image:NewTrackingTools.PNG|800px]]
In the Tracking Tools Quick Start pop up menu select Open Existing Project and then navigate to ''D:\Optitrack_Configuration'' (It should open to this directory by default) and select the most recent Tracking Tools project. It should be named like ''TrackingToolsProject YYYY-MM-DD timeStamp.ttp''. This is normally the most recently edited file when sorting by data modified. The most recent one as of August 1st, 2016 is ''TrackingToolsProject 2015-09-23 2.30pm.ttp''.
[[Image:OpeningProject.PNG|800px]]
You should notice that the cameras shown in main project scree arrange themselves like out camera configuration once the project has been opened. Now the constellations need to be loaded. This can be done by going to ''File->Open'' and another pop up window will open. Navigate back to ''D:\Optitrack_Configuration'' (It should open to this directory by default) and select the most recently dated set of RADA trackables. They are named like ''RADA_entireSystem_M_D_YYYY.tra''. The most recent one as of August 1st, 2016 is ''RADA_entireSystem_7_8_2016.tra''.
[[Image:Opening_trackables.PNG|800px]]
Once the project and trackless are open the cameras should appear in their constellation (square) and there should be two constellations under ''Project Explorer->Trackables''. One Named UAV for the pendulum and one named ERIS for the ground vehicle. In order to get additional information about each constellation left click on the the name of the desired trackable.
[[Image:SelectingUAV.PNG|800px]]
Once a trackable is selected more information about it is available in the ''Trackables'' Tab on the right side of the screen. For the current position and orientation look at the ''Real-Time Info'' sub-tab. This gives the orientation in the wrong order for how we currently use the Euler angles. When two or three of the angles are near zero you can switch yaw and pitch to get roughly the correct orientation.
[[Image:Uav_realTimeInfo.PNG|800px]]
Now we need check to make sure the system is zeroed.
1. Hold RADA so that the front of the ground robot (ERIS is facing the wall with the white boards (east)). The front side of Eris is labeled. If it isn't it is the side opposite of the switches and the side with the trackable constellation on it.
2. Make sure that the motor with the red motor mount is also facing the wall with the white boards.
3. Make sure the quad system is aligned along Eris Axis by standing behind the system and seeing if you can use the pole to block mounting bolts of the front propeller motor mount when looking at the pole while facing the east wall.
4. While holding the pendulum approximately vertical see if the camera system reads zeros for the pendulum (UAV) pitch and roll (yaw and roll in ''Real-Time Info''). If yaw is off by a few degrees that is fine.
5. Compare the yaw of the UAV to that of ERIS (Remember this is pitch in ''Real-Time Info''). If they are both near zero and with in a few degrees and the pendulum's pitch/roll were also near zero then you are ready to use the camera system. Otherwise go to the next step.
6. You need to zero the pendulum.
- Align ERIS so it is near zero yaw first (eye ball it).
- Get a level and a friend. Have your friend use a level to ensure that the pendulum is level in both directs and hold it there.
- With the UAV constellation selected go to the ''Orientation'' tab (next to ''Real-Time Info'' tab) and click on ''Reset To Current Orientation button''
- Now your friend can set the pendulum down and you can zero ERIS the same way.
7. Save the new trackable orientation by going to ''File->Save Trakables...'' and save a file using the same naming conventions as the trackable file you opened earlier except use the current data so you don't have to re-zero the system the next time you test.
[[Image:Uav_ResetOrientation.PNG|800px]]
=== Building Software ===
The development environment for running RADA is hosted on CO3050-11, a Linux Red Hat environment. This computer has a local ucart user name that you should use. The password isn't put here for security reasons. In order to ensure that the RADA software is setup correctly for the test you want to run. To do this you will need to open the main.cpp and logger.cpp files and make sure all of the compile time macros you want are defined correctly. All of the c++ files you should need to edit are in the directory ''~/Desktop/rada_research_project/ErisResearchCode/CppProjects/MainProgram_PacketLoss/src/Korebot'' Below is a compiler macro options for main.cpp:
-'''H2ctrl''' : This will cause the system to enter H2 controller mode where the whole RADA system is controlled by an H2 controller.
-'''ssTracking''' : H2ctrl must also be defined for this macro to do anything. This macro will has the system to be controlled by a tracking H2 controller.
-'''ssMotors''' : H2ctrl must also be defined for this macro to do anything. This macro will has the system to be controlled by an H2 contorller that contains propeller states. This also cause the system to "Dance."
-'''ssDrop''' : Cause the system to go into packet drop controller mode. This mode allows controllers designed for lossy networks to be tested. Based off of other definitions how lossy the network is can be simulated. If nothing else is defined this controller becomes basically a H2 controller.
-'''drop10''' : Will put the packet drop mode into 10% loss mode and use a controller designed for 10% loss.
-'''drop30''' : Will put the packet drop mode into 30% loss mode and use a controller designed for 30% loss.
-'''drop50''' : Will put the packet drop mode into 50% loss mode and use a controller designed for 50% loss.
-'''mot50''' : This macro over-rides all other macros. If this is turned on the wheels will not run and the propllers will be run at 50% command. This is used for measuring the effective battery voltage seen by the ESCs. This is always run after a test.
-'''RADAlqi''' : This macro will cause the system to use an LQI controller on the whole system. The linear velocity states are calculated with no filter and the angular velocity states are calculated with filters.
-'''RADAlqi_est''' : This macro will cause the system to use an LQI controller on the whole system. A traditional estimator is used to estimate the states.
-'''rada_lqg''' : This macro will cause the entire system to be controlled by a LQG controller/estimator system.
-'''rada_split_lqg''' : This macro will cause the pendulum and ground robot to be controlled by their own LQG systems.
-'''rada_split_lqg_ol''' : This macro will cause the pendulum to be controlled by an LQG controller, the yaw of the ground robot to be controlled by a PID controller, and the ground robot linear velocities to be controlled with open-loop commands.
-'''yaw_off''' : This macro will cause the yaw control to be disabled on some controllers.
*'''accR''' : This macro will cause the PID linear velocity controllers to be given ramps to acclerate from one velocity to another instead of steps.
-'''posRamp''' : This macro will cause the linear velocities of RADA to be controlled by position PIDs with ramp reference instead of velocity commands.
-If no controller selection is made all controllers revert to PID controllers
All of these macros can be defined simply by uncommenting the corresponding define statement in main.cpp. The macros in the logger.cpp can be seen below:
-'''ssDrop''' : This macro puts the logger into packed drop controller mode and logs the correct values for the packet drop controllers.
-'''RADAlqi''' : This macro puts the logger into full system LQI controller logging mode.
-'''RADAlqi_est''' : This macro puts the logger into full system LQI controller plus estimator logging mode.
-'''rada_lqg''' : This puts the logger into full system LQG controller logging mode.
-'''rada_split_lqg''' : This macro causes the logger to log data about the subsystem LQG controllers.
-'''rada_split_lqg_ol''' : This cause the system to log data about the pendulum LQG system and the open-loop linear velocity commands.
-'''H2ctrl''' : This macro causes the logger to log data about the full system H2 controllers.
-If no logging mode is selected then the logger will default to logging PID data.
Because the system only calculates controllers for one set of controllers it is important to ensure that the logger is in the correct mode based off of what is defined in main.cpp. As of August 1st, 2016 the defines in main.cpp are not seen in logger.cpp.
Finally in a command prompt navigate to the driectroy: ''~/Desktop/rada_research_project/ErisResearchCode/CppProjects/MainProgram_PacketLoss''
Here just type: ''make''. The code will compile for your desired mode. For setting up a new development directory see [http://wikis.ece.iastate.edu/robotic-agriculture-data-acquisition/index.php/Setting_up_a_new_development_environment Setting up a new development environment] from the RADA senior Design wiki.
[[Image:ComplingRADACode.png|800px]]
The complied executable code ends up in ''/home/shared/MainProject''. The ''/home/shared'' directory is setup as a network file share (NFS).
[[Image:ErisCompliedCode-config.png|800px]]
This service needs to be restarted when CO3050-11 is restarted. [http://wikis.ece.iastate.edu/robotic-agriculture-data-acquisition/index.php/Configuring_NFS_shares_for_the_robot Configure NFS shares for the robot] from the RADA Senior Design wiki. Be sure to use the new Linux install command in step six. Though I have fond that even on a good strt the ''[ok]'' messages will still print.
=== Turing on RADA ===
Turing on Eris is fairly simple. Each system has its own battery. There is one for the wheels that plugs in at the front of Eris (opposite side of the swiches), one for the electronics in the back of Eris (in between the switches), and one for the propellers that goes on top of Eris.
[[Image:ErisOnPhoto.jpg|800px]]
The wheel battery is normally 1600 mAh 2-cell Lipo but any 2-cell Lipo will work. The wheels are turned on by flipping the silver switch so the top points away from the system. The electronics normally use a 2600 mAh 2-cell Lipo. The electronics are turned on by flipping the green switch away from the system. It is important that you only the WIFI adapter or Ethernet plugged in at the same time or VRPN my listen to the camera data broadcast over both connects which could cause problems. The propeller system is powered via a 2600 mAh 4-cell Lipo that connects to a power cable at the base of the pendulum. There is a switch to turn on the power to the propellers system. You will know it is on when the 1 on the switch is flush with the switch housing instead of sticking out. It takes about 30 seconds to a minute for Eris to boot up and start the networking connections. When the WIFI is plugged in you will know it is ready when a blue light turns on, on the module.
=== Connecting to RADA ===
RADA is controlled through an SSH connection. in a commands prompt, not the one you compile the code from so that you can recompile for different setup with out needing to close the connection. If you are using a WIFI connect use the command ''ssh root@192.168.0.53''. If you are connected to Eris through a LAN connaction use the command ''ssh root@192.168.0.54''. If the connection goes though you should be proped for a password.
The password is ''rootme''.
[[Image:Ssh2Eris.png|800px]]
It is important to close the SSH connection before turning off Eris because the terminal you are using will hang up if you don't. You can close the connection by using the command ''exit''.
[[Image:ClosingSSH.png|800px]]
== Testing RADA ==
Now that you are connected to Eris you can run tests. The testing is started by a few different methods.
=== Running the first test after power up ===
For the firs test after powering on Eris a few additional steps need to be completed in order to test the system. The FPGA motor controller needs to be programmed and Eris needs to connect the the NFS server running on CO3050-11. This is accomplished by running ''1_co3050-11.sh'', this shell scrip will setup the NFS, load the bit file into the FPGA configuration memory. Then it retrieves the executable file from the NFS server ''/mnt/nfs/MainProject and runs the executable. Once the user exits the executable the log file produces is copied from the ''~/Logs/YYYY_MM_DD_Day'' directory on Eris to ''/home/shared/MainProject/Logs/YYYY_MM_DD_Day'' on CO3050-11. When the folder for the current Eris date doesn't exist it creates this directory in CO3050-11 and then removes the directory and log file from Eris. You may see an warning that when coping the log file Eris couldn't maintain the file permisiion settings. This is normal as Eris doesn't have the same access to the NSF server as it has to its own files. This Date stamp uses date on Eris which is currently in June of 2008 as of August 2nd, 2016.
Before starting the test it is best to have someone spotting the pendulum a holding it near vertical so that the pendulum doesn't have issues when entering a control mode.'''<span style="color:red"> Always run ensure the pendulum is spotted by a second person when testing so you don't hurt yourself, others in the lab, or the RADA system.</span>''' Once you spotter is ready run the shell scrip by= using the command ''./1_co3050-11.sh'' in the terminal with the open SSH connection to Eris from the home, ''/root'', directory of Eris. When you run this script there will be a bunch of information printed out about the PIC bus and loading the bit file to configure the FPGA, you will know that RADA is ready for the test when it asks you to select a running mode. See the Testing Modes section below. This script can take a while to complete so beyond the first test after start up you don't need to run this script. See the Section about Running additional tests below.
[[Image:StartingRADA initial.png|800px]]
=== Testing Modes ===
The RADA system has three testing modes: Robot Control Mode, Tuning Mode, and Box Step Mode. Additionally you can exit the execution at any time by pressing the ''Esc'' key. Once the terminal asks you to chose a mode you can use the following commands to enter the desired mode with a three second delay or exit the program. You can also use these commands to switch between the modes.
-''v'' : Enters the pendulum PID tuning mode, this will only really work when using PIDs to control the pendulum.
-''b'' : Enter Robot control mode, in this mode you can drive the robot around and the pendulum will try to stay vertical. This is the main mode used for testing the whole RADA system.
-''n'' : Enters box step mode, where the pendulum will change its desired pitch and roll angles every 20 seconds and move in a box shape.
-''Esc'' : By hitting the escape key the program will exit the program.
You will almost always want to run Robot Control Mode as the other modes are legacy modes from when we initially built and tested RADA and only works with the pendulum PID controllers. There are also a few utility commands that can be used in all modes.
-''2'' : Resets I composts of the Pitch/Roll PIDs and only the PIDs.
-''m'' : Adds a marker to the Log file incase odd things happen somewhere. This just increments a counter so if you use it look for changes in the marker value.
==== Robot Control Model ====
In Robot control mode you can control the motion of Eris. For PID control of Eris or 1D state feedback system the directional commands command Eris body velocity were for full system and Eris system state feedback controllers control the global velocity. All of these keys only need to be pressed not held down.
-''w'' : Moves Eris forward (+x) at some velocity depending on the controller.
-''s'' : Moves Eris in reverse (-x) at some velocity depending on the controller.
-''d'' : Moves Eris in right (+y) at some velocity depending on the controller.
-''a'' : Moves Eris in left (-y) at some velocity depending on the controller.
-''p'' : Stops the motion of Eris (Set all velocity set points to zero). I.e. if you hit ''w'' then hit ''s'' then Eris will be moving in reverse.
-''y'' : Moves Eris forward and to the right (+x/+y) simultaneously at some velocity depending on the controller.
-''t'' : Moves Eris forward and to the left (+x/-y) simultaneously at some velocity depending on the controller.
-''i'' : Moves Eris reverse and to the right (-x/+y) simultaneously at some velocity depending on the controller.
-''y'' : Moves Eris reverse and to the left (-x/-y) simultaneously at some velocity depending on the controller.
-''e'' : Rotate Eris clockwise (+yaw) at some angular rate. This only worked when RADA used the closed-loop FPGA control of the wheels. There is currently no controllers that use this command.
-''q'' : Rotate Eris counter-clockwise (-yaw) at some angular rate. This only worked when RADA used the closed-loop FPGA control of the wheels. There is currently no controllers that use this command.
-''<'' : Increment Eris' desired heading 45 degrees counter-clockwise (-yaw).
-''>'' : Increment Eris' desired heading 45 degrees clockwise (+yaw).
-''7'' : Increments the pitch set point (+pitch).
-''4'' : Decrements the pitch set point (-pitch).
-''8'' : Increments the roll set point (+roll).
-''5'' : Decrements the roll set point (-roll).
==== Tuning Mode ====
Tuning mode allows you to tune the PID controllers for both pitch and roll. The UI commands here are also available in Box Step Mode.
-''1'' : Tune the Pitch PID.
-''3'' : Tune the Roll PID.
-''7'' : Increase proportional gain of PID being tuned.
-''4'' : Decrease proportional gain of PID being tuned.
-''8'' : Increase integral gain of PID being tuned.
-''5'' : Decrease integral gain of PID being tuned.
-''9'' : Increase derivative gain of PID being tuned.
-''6'' : Decrease derivative gain of PID being tuned.
-''i'' : Increase set point of PID being tuned.
-''k'' : Decrease set point of PID being tuned.
-''o'' : Increase integral windup term of PID being tuned. (Not used)
-''l'' : Decrease integral windup term of PID being tuned. (Not used)
==== Box Step Mode ====
Box set mode will automatically change the set points of the pendulum every 20 seconds. The case statement for this mode can be changed for 1D and 2D step modes. This mode allows the user to use he same commands as Tuning Mode.
=== Running additional Tests ===
Once you have run one test with Eris on it is unnecessary to configure the FPGA or connect to the NFS server again. This is what took much of the time in the initial setup. This is what the script ''3_stat_eris.sh'' was developed for. It does everything that ''1_co3050-11.sh'' does but without reprogramming the FPGA or reconnecting to the NFS server. As a result it is ready to test much quicker.
Before starting the test it is best to have someone spotting the pendulum a holding it near vertical so that the pendulum doesn't have issues when entering a control mode.'''<span style="color:red"> Always run ensure the pendulum is spotted by a second person when testing so you don't hurt yourself, others in the lab, or the RADA system.</span>''' Once you spotter is ready run the shell scrip by= using the command ''./3_start_eris.sh'' in the terminal with the open SSH connection to Eris from the home, ''/root'', directory of Eris.
[[Image:StartingRADA2nd.png|800px]]
=== Locating and retrieving log files ===
Once you are done with a test that you want to compare to the model you should retrieve the log file right away so you don't mix it up with other test. On CO3050-11 go to the dircetory ''/home/shared/MainProject/Logs'' using the file browser (you can do this in a terminal but it is easier from the file explorer). Once there, look for the folder that has been modified most recently as Eris date is normally out of sync with its date and time. Then look for the newest log file. Log files are named like ''log(hh.mm.ss).txt'' (ex. log(13.04.51).txt). This naming convention works well to ensure that no log file is over written but it isn't useful of describing what the test was of or for. Copy this log to the Desktop or to a USB drive and rename it. A good method is to name the file something like ''RADA_ctrl_otherNote#.txt'', where Describes what system you tested (ex. RADA, RADA1D, PEN1D, PEN2D), what typ of controller was used, other notes and then a number if this is a repeat of another test. This is much more useful when looking back at these logs later on. Before transferring the log file for processing you should record the wheel and propeller battery voltages in the header of the log file. The log file format is both human readable and can be parsed by MATALB. It was designed by the first RADA Senior Design Team and more information about the log files can be found [http://wikis.ece.iastate.edu/robotic-agriculture-data-acquisition/index.php/Data_Analysis_Tool here.] See he section below on measuring battery voltage below in order to get the best measurements for simulation of RADA.
=== Measuring battery voltages ===
The last thing that you need to do before simulating an experiment of the RADA platform is record the battery voltages for both the wheels and propellers. The wheel battery can be measured unloaded as there isn't large line losses between the battery and the H-bridges. The propeller battery voltage needs to be measured under load because the power cord running up the pendulum has significant line losses at the currents the propellers draw when in use. The battery voltages can be recorded in the log file for the test. Open the log file for the test you just completed (Use KWrite for Linux machines or Notepad++ for Windows machines). The first few lines of the log is the headder. It should look like this:
#Constants pitch_P pitch_I pitch_D
#PIDValues 48000 18000 21000
#Constants roll_P roll_I roll_D
#PIDValues 48000 18000 21000
#Battery Vquad Vwheels
#Voltage
Follow the procedure for measuring the voltage of each battery and then record the voltage under the corresponding battery. Then save the log file and close out of your text editor and the test will be ready for processing. Recoding the battery voltages in this way makes it much easier to find if you need the value latter. The final log file header should look like this once you are done
#Constants pitch_P pitch_I pitch_D
#PIDValues 48000 18000 21000
#Constants roll_P roll_I roll_D
#PIDValues 48000 18000 21000
#Battery Vquad Vwheels
#Voltage 14.44 8.257
==== Wheel Battery ====
1. After test disconnect wheel battery from the system.
2. Measure voltage of battery using multimeter.
[[Image:MeasureVwheel.jpg|800px]]
You can use the plug used for charging the 2-cell Lipos but make sure to connect the plug to the multimeter before connecting the battery and disconnect the battery before disconnecting the plug from the mulitmeter. It is generally the best practice to give the multimeter a few minutes to allow for the voltage measurement to stabilize as the battery measurement tends to be a little low right after the test.
==== Quad Battery ====
1. Setup code to run all four propellers at 50% throttle, uncomment the definition of ''mot50'' in main.cpp and compile the project.
2. Power off propellers by turning off the switch to the ESCs.
3. Connect multimeter to measure the voltage across one of the ESCs. This is done by using the power splitter cord.
-Connect one of the female XT60 connectors on the splitter to a male XT60 connector to banana connector cable.
-The banana connector connect to the hand held multimeter. The multimeter should be set to the 20VDC measurement setting.
-Next unplug one the ESCs' power connection.
-reconnect the ESC to power through the two remain connectors on the spliter cable.
4. Power on the propellers.
5. Run the system at 50% throttle and measure the steady-state voltage during the test. The battery will slow the voltage decay significantly, meaning it will keep the same measurement for a few seconds.
6. Stop the test and record the voltage in the log file.
{| class="wikitable" style="text-align:center"
|-
| [[Image:PowerSplitter.jpg|200px]]
| [[Image:QuadMultiCon.jpg |200px]]
| [[Image:QuadMultiSet.JPG |200px]]
| [[Image:QuadMeasESCcon.JPG|200px]]
|-
| Splitter cord.
| Connect splitter to multimeter.
| Settings for multimeter.
| Connecting ESC through splitter.
|}
The testing setup should look like the image below:
[[Image:QuadBattMeas.jpg|800px]]
== Post processing and Simulation ==
=== Using the MATLAB data parsing tool ===
=== Adding additional data for simulations ===
=== Setting up the MATLAB workspace for simulation ===
=== Running simulations and storing results ===
=== Plotting results ===
17640831ca143a35cbb470248baf3558b5c90a1d
258
257
2016-08-02T20:53:47Z
Pfuhing
5
/* Quad Battery */
wikitext
text/x-wiki
This page will take you though setting up and testing RADA, retrieving the log file and other necessary data to run a simulation of that test and processing the data in MATLAB. Then actually running the simulation of RADA in Simulink.
== Setting Up a RADA Test ==
Testing RADA is not overly difficult once you get the hang of the steps to setup RADA. The following steps may seem like a long process to go from starting the testing process to having completed simulation and plotting of the test results but this whole test procedure (with the exception of battery charging) can be completed in about 15-20 minutes. These steps are meant to be as detailed as possible in order to help new users of RADA to get up and running as quickly as possible.
'''<span style="color:red">NOTE: Always run RADA with at least 2 people!</span>''' The pendulum arm can crash into the ground if the network starts to drop packets and one person cannot give commands to RADA and spot the pendulum. This is a safety issue for both you and the RADA platform.
=== Charging batteries ===
The lab currently uses mostly Hyperion batteries. We charge our batteries with a Hyperion EOS 1420i Net3 battery charger. For some general information about how to use this charger see [https://www.youtube.com/watch?v=-ox3EpzvsJ8 this video.]. In the lab we power this charger using the old Kepco Power supplu because it is the only power supply that we have that can supply enough current. Make sure that the power supply is set to an output voltage between 10.5V-29V.
{| class="wikitable" style="text-align:center"
|-
| [[Image:ChargerPowerSupplyOff.JPG|400px]]
| [[Image:ChargerPowerSuplyOn.JPG|400px]]
|-
| Kepco Power Supply off.
| Kepco Power Supply on with correct voltage supply range.
|}
While the YouTube video linked above should explain how to use the charger. Currently three different Lithium polymer batteries (Lipo): 1600 mAh 2-cell Lipo for the wheels, 2600 mAh 2-cell Lipo for the electronics of Eris, and a 2600 mAh 4-cell Lipo. The 1600 mAh 2-cell Lipo can be charged using memory slot 2 of the charger. The 2600 mAh 2-cell Lipos can be charged using memory slot 3 for fast charging and memory slot 4 for slower charging (use this if the battery gets run really low for 10-20 minutes then switch to fast charging). The 2600 mAh 4-cell Lipo can be charged using memory slot 8. The 1600 mAh 2-cell and 2600 mAr 4-cell generally charge in 10-20 minutes apiece while I generally fine it takes the 2600 mAh 2-cell up to 70 minutes to charge fully.
=== Setting up the camera system ===
The camera system is run on the windows computer CO3050-07. You can log into this computer using a local microcart username and password which is not posted here for security reasons but any one who works in the lab should know it. Once logged in look for Tracking Tools in the start menu or look for the shortcut shown below:
[[Image:TrackingTools_shortcut.PNG|thumb|center|Tracking Tools shortcut]]
Once the program opens the screen should look something like this:
[[Image:NewTrackingTools.PNG|800px]]
In the Tracking Tools Quick Start pop up menu select Open Existing Project and then navigate to ''D:\Optitrack_Configuration'' (It should open to this directory by default) and select the most recent Tracking Tools project. It should be named like ''TrackingToolsProject YYYY-MM-DD timeStamp.ttp''. This is normally the most recently edited file when sorting by data modified. The most recent one as of August 1st, 2016 is ''TrackingToolsProject 2015-09-23 2.30pm.ttp''.
[[Image:OpeningProject.PNG|800px]]
You should notice that the cameras shown in main project scree arrange themselves like out camera configuration once the project has been opened. Now the constellations need to be loaded. This can be done by going to ''File->Open'' and another pop up window will open. Navigate back to ''D:\Optitrack_Configuration'' (It should open to this directory by default) and select the most recently dated set of RADA trackables. They are named like ''RADA_entireSystem_M_D_YYYY.tra''. The most recent one as of August 1st, 2016 is ''RADA_entireSystem_7_8_2016.tra''.
[[Image:Opening_trackables.PNG|800px]]
Once the project and trackless are open the cameras should appear in their constellation (square) and there should be two constellations under ''Project Explorer->Trackables''. One Named UAV for the pendulum and one named ERIS for the ground vehicle. In order to get additional information about each constellation left click on the the name of the desired trackable.
[[Image:SelectingUAV.PNG|800px]]
Once a trackable is selected more information about it is available in the ''Trackables'' Tab on the right side of the screen. For the current position and orientation look at the ''Real-Time Info'' sub-tab. This gives the orientation in the wrong order for how we currently use the Euler angles. When two or three of the angles are near zero you can switch yaw and pitch to get roughly the correct orientation.
[[Image:Uav_realTimeInfo.PNG|800px]]
Now we need check to make sure the system is zeroed.
1. Hold RADA so that the front of the ground robot (ERIS is facing the wall with the white boards (east)). The front side of Eris is labeled. If it isn't it is the side opposite of the switches and the side with the trackable constellation on it.
2. Make sure that the motor with the red motor mount is also facing the wall with the white boards.
3. Make sure the quad system is aligned along Eris Axis by standing behind the system and seeing if you can use the pole to block mounting bolts of the front propeller motor mount when looking at the pole while facing the east wall.
4. While holding the pendulum approximately vertical see if the camera system reads zeros for the pendulum (UAV) pitch and roll (yaw and roll in ''Real-Time Info''). If yaw is off by a few degrees that is fine.
5. Compare the yaw of the UAV to that of ERIS (Remember this is pitch in ''Real-Time Info''). If they are both near zero and with in a few degrees and the pendulum's pitch/roll were also near zero then you are ready to use the camera system. Otherwise go to the next step.
6. You need to zero the pendulum.
- Align ERIS so it is near zero yaw first (eye ball it).
- Get a level and a friend. Have your friend use a level to ensure that the pendulum is level in both directs and hold it there.
- With the UAV constellation selected go to the ''Orientation'' tab (next to ''Real-Time Info'' tab) and click on ''Reset To Current Orientation button''
- Now your friend can set the pendulum down and you can zero ERIS the same way.
7. Save the new trackable orientation by going to ''File->Save Trakables...'' and save a file using the same naming conventions as the trackable file you opened earlier except use the current data so you don't have to re-zero the system the next time you test.
[[Image:Uav_ResetOrientation.PNG|800px]]
=== Building Software ===
The development environment for running RADA is hosted on CO3050-11, a Linux Red Hat environment. This computer has a local ucart user name that you should use. The password isn't put here for security reasons. In order to ensure that the RADA software is setup correctly for the test you want to run. To do this you will need to open the main.cpp and logger.cpp files and make sure all of the compile time macros you want are defined correctly. All of the c++ files you should need to edit are in the directory ''~/Desktop/rada_research_project/ErisResearchCode/CppProjects/MainProgram_PacketLoss/src/Korebot'' Below is a compiler macro options for main.cpp:
-'''H2ctrl''' : This will cause the system to enter H2 controller mode where the whole RADA system is controlled by an H2 controller.
-'''ssTracking''' : H2ctrl must also be defined for this macro to do anything. This macro will has the system to be controlled by a tracking H2 controller.
-'''ssMotors''' : H2ctrl must also be defined for this macro to do anything. This macro will has the system to be controlled by an H2 contorller that contains propeller states. This also cause the system to "Dance."
-'''ssDrop''' : Cause the system to go into packet drop controller mode. This mode allows controllers designed for lossy networks to be tested. Based off of other definitions how lossy the network is can be simulated. If nothing else is defined this controller becomes basically a H2 controller.
-'''drop10''' : Will put the packet drop mode into 10% loss mode and use a controller designed for 10% loss.
-'''drop30''' : Will put the packet drop mode into 30% loss mode and use a controller designed for 30% loss.
-'''drop50''' : Will put the packet drop mode into 50% loss mode and use a controller designed for 50% loss.
-'''mot50''' : This macro over-rides all other macros. If this is turned on the wheels will not run and the propllers will be run at 50% command. This is used for measuring the effective battery voltage seen by the ESCs. This is always run after a test.
-'''RADAlqi''' : This macro will cause the system to use an LQI controller on the whole system. The linear velocity states are calculated with no filter and the angular velocity states are calculated with filters.
-'''RADAlqi_est''' : This macro will cause the system to use an LQI controller on the whole system. A traditional estimator is used to estimate the states.
-'''rada_lqg''' : This macro will cause the entire system to be controlled by a LQG controller/estimator system.
-'''rada_split_lqg''' : This macro will cause the pendulum and ground robot to be controlled by their own LQG systems.
-'''rada_split_lqg_ol''' : This macro will cause the pendulum to be controlled by an LQG controller, the yaw of the ground robot to be controlled by a PID controller, and the ground robot linear velocities to be controlled with open-loop commands.
-'''yaw_off''' : This macro will cause the yaw control to be disabled on some controllers.
*'''accR''' : This macro will cause the PID linear velocity controllers to be given ramps to acclerate from one velocity to another instead of steps.
-'''posRamp''' : This macro will cause the linear velocities of RADA to be controlled by position PIDs with ramp reference instead of velocity commands.
-If no controller selection is made all controllers revert to PID controllers
All of these macros can be defined simply by uncommenting the corresponding define statement in main.cpp. The macros in the logger.cpp can be seen below:
-'''ssDrop''' : This macro puts the logger into packed drop controller mode and logs the correct values for the packet drop controllers.
-'''RADAlqi''' : This macro puts the logger into full system LQI controller logging mode.
-'''RADAlqi_est''' : This macro puts the logger into full system LQI controller plus estimator logging mode.
-'''rada_lqg''' : This puts the logger into full system LQG controller logging mode.
-'''rada_split_lqg''' : This macro causes the logger to log data about the subsystem LQG controllers.
-'''rada_split_lqg_ol''' : This cause the system to log data about the pendulum LQG system and the open-loop linear velocity commands.
-'''H2ctrl''' : This macro causes the logger to log data about the full system H2 controllers.
-If no logging mode is selected then the logger will default to logging PID data.
Because the system only calculates controllers for one set of controllers it is important to ensure that the logger is in the correct mode based off of what is defined in main.cpp. As of August 1st, 2016 the defines in main.cpp are not seen in logger.cpp.
Finally in a command prompt navigate to the driectroy: ''~/Desktop/rada_research_project/ErisResearchCode/CppProjects/MainProgram_PacketLoss''
Here just type: ''make''. The code will compile for your desired mode. For setting up a new development directory see [http://wikis.ece.iastate.edu/robotic-agriculture-data-acquisition/index.php/Setting_up_a_new_development_environment Setting up a new development environment] from the RADA senior Design wiki.
[[Image:ComplingRADACode.png|800px]]
The complied executable code ends up in ''/home/shared/MainProject''. The ''/home/shared'' directory is setup as a network file share (NFS).
[[Image:ErisCompliedCode-config.png|800px]]
This service needs to be restarted when CO3050-11 is restarted. [http://wikis.ece.iastate.edu/robotic-agriculture-data-acquisition/index.php/Configuring_NFS_shares_for_the_robot Configure NFS shares for the robot] from the RADA Senior Design wiki. Be sure to use the new Linux install command in step six. Though I have fond that even on a good strt the ''[ok]'' messages will still print.
=== Turing on RADA ===
Turing on Eris is fairly simple. Each system has its own battery. There is one for the wheels that plugs in at the front of Eris (opposite side of the swiches), one for the electronics in the back of Eris (in between the switches), and one for the propellers that goes on top of Eris.
[[Image:ErisOnPhoto.jpg|800px]]
The wheel battery is normally 1600 mAh 2-cell Lipo but any 2-cell Lipo will work. The wheels are turned on by flipping the silver switch so the top points away from the system. The electronics normally use a 2600 mAh 2-cell Lipo. The electronics are turned on by flipping the green switch away from the system. It is important that you only the WIFI adapter or Ethernet plugged in at the same time or VRPN my listen to the camera data broadcast over both connects which could cause problems. The propeller system is powered via a 2600 mAh 4-cell Lipo that connects to a power cable at the base of the pendulum. There is a switch to turn on the power to the propellers system. You will know it is on when the 1 on the switch is flush with the switch housing instead of sticking out. It takes about 30 seconds to a minute for Eris to boot up and start the networking connections. When the WIFI is plugged in you will know it is ready when a blue light turns on, on the module.
=== Connecting to RADA ===
RADA is controlled through an SSH connection. in a commands prompt, not the one you compile the code from so that you can recompile for different setup with out needing to close the connection. If you are using a WIFI connect use the command ''ssh root@192.168.0.53''. If you are connected to Eris through a LAN connaction use the command ''ssh root@192.168.0.54''. If the connection goes though you should be proped for a password.
The password is ''rootme''.
[[Image:Ssh2Eris.png|800px]]
It is important to close the SSH connection before turning off Eris because the terminal you are using will hang up if you don't. You can close the connection by using the command ''exit''.
[[Image:ClosingSSH.png|800px]]
== Testing RADA ==
Now that you are connected to Eris you can run tests. The testing is started by a few different methods.
=== Running the first test after power up ===
For the firs test after powering on Eris a few additional steps need to be completed in order to test the system. The FPGA motor controller needs to be programmed and Eris needs to connect the the NFS server running on CO3050-11. This is accomplished by running ''1_co3050-11.sh'', this shell scrip will setup the NFS, load the bit file into the FPGA configuration memory. Then it retrieves the executable file from the NFS server ''/mnt/nfs/MainProject and runs the executable. Once the user exits the executable the log file produces is copied from the ''~/Logs/YYYY_MM_DD_Day'' directory on Eris to ''/home/shared/MainProject/Logs/YYYY_MM_DD_Day'' on CO3050-11. When the folder for the current Eris date doesn't exist it creates this directory in CO3050-11 and then removes the directory and log file from Eris. You may see an warning that when coping the log file Eris couldn't maintain the file permisiion settings. This is normal as Eris doesn't have the same access to the NSF server as it has to its own files. This Date stamp uses date on Eris which is currently in June of 2008 as of August 2nd, 2016.
Before starting the test it is best to have someone spotting the pendulum a holding it near vertical so that the pendulum doesn't have issues when entering a control mode.'''<span style="color:red"> Always run ensure the pendulum is spotted by a second person when testing so you don't hurt yourself, others in the lab, or the RADA system.</span>''' Once you spotter is ready run the shell scrip by= using the command ''./1_co3050-11.sh'' in the terminal with the open SSH connection to Eris from the home, ''/root'', directory of Eris. When you run this script there will be a bunch of information printed out about the PIC bus and loading the bit file to configure the FPGA, you will know that RADA is ready for the test when it asks you to select a running mode. See the Testing Modes section below. This script can take a while to complete so beyond the first test after start up you don't need to run this script. See the Section about Running additional tests below.
[[Image:StartingRADA initial.png|800px]]
=== Testing Modes ===
The RADA system has three testing modes: Robot Control Mode, Tuning Mode, and Box Step Mode. Additionally you can exit the execution at any time by pressing the ''Esc'' key. Once the terminal asks you to chose a mode you can use the following commands to enter the desired mode with a three second delay or exit the program. You can also use these commands to switch between the modes.
-''v'' : Enters the pendulum PID tuning mode, this will only really work when using PIDs to control the pendulum.
-''b'' : Enter Robot control mode, in this mode you can drive the robot around and the pendulum will try to stay vertical. This is the main mode used for testing the whole RADA system.
-''n'' : Enters box step mode, where the pendulum will change its desired pitch and roll angles every 20 seconds and move in a box shape.
-''Esc'' : By hitting the escape key the program will exit the program.
You will almost always want to run Robot Control Mode as the other modes are legacy modes from when we initially built and tested RADA and only works with the pendulum PID controllers. There are also a few utility commands that can be used in all modes.
-''2'' : Resets I composts of the Pitch/Roll PIDs and only the PIDs.
-''m'' : Adds a marker to the Log file incase odd things happen somewhere. This just increments a counter so if you use it look for changes in the marker value.
==== Robot Control Model ====
In Robot control mode you can control the motion of Eris. For PID control of Eris or 1D state feedback system the directional commands command Eris body velocity were for full system and Eris system state feedback controllers control the global velocity. All of these keys only need to be pressed not held down.
-''w'' : Moves Eris forward (+x) at some velocity depending on the controller.
-''s'' : Moves Eris in reverse (-x) at some velocity depending on the controller.
-''d'' : Moves Eris in right (+y) at some velocity depending on the controller.
-''a'' : Moves Eris in left (-y) at some velocity depending on the controller.
-''p'' : Stops the motion of Eris (Set all velocity set points to zero). I.e. if you hit ''w'' then hit ''s'' then Eris will be moving in reverse.
-''y'' : Moves Eris forward and to the right (+x/+y) simultaneously at some velocity depending on the controller.
-''t'' : Moves Eris forward and to the left (+x/-y) simultaneously at some velocity depending on the controller.
-''i'' : Moves Eris reverse and to the right (-x/+y) simultaneously at some velocity depending on the controller.
-''y'' : Moves Eris reverse and to the left (-x/-y) simultaneously at some velocity depending on the controller.
-''e'' : Rotate Eris clockwise (+yaw) at some angular rate. This only worked when RADA used the closed-loop FPGA control of the wheels. There is currently no controllers that use this command.
-''q'' : Rotate Eris counter-clockwise (-yaw) at some angular rate. This only worked when RADA used the closed-loop FPGA control of the wheels. There is currently no controllers that use this command.
-''<'' : Increment Eris' desired heading 45 degrees counter-clockwise (-yaw).
-''>'' : Increment Eris' desired heading 45 degrees clockwise (+yaw).
-''7'' : Increments the pitch set point (+pitch).
-''4'' : Decrements the pitch set point (-pitch).
-''8'' : Increments the roll set point (+roll).
-''5'' : Decrements the roll set point (-roll).
==== Tuning Mode ====
Tuning mode allows you to tune the PID controllers for both pitch and roll. The UI commands here are also available in Box Step Mode.
-''1'' : Tune the Pitch PID.
-''3'' : Tune the Roll PID.
-''7'' : Increase proportional gain of PID being tuned.
-''4'' : Decrease proportional gain of PID being tuned.
-''8'' : Increase integral gain of PID being tuned.
-''5'' : Decrease integral gain of PID being tuned.
-''9'' : Increase derivative gain of PID being tuned.
-''6'' : Decrease derivative gain of PID being tuned.
-''i'' : Increase set point of PID being tuned.
-''k'' : Decrease set point of PID being tuned.
-''o'' : Increase integral windup term of PID being tuned. (Not used)
-''l'' : Decrease integral windup term of PID being tuned. (Not used)
==== Box Step Mode ====
Box set mode will automatically change the set points of the pendulum every 20 seconds. The case statement for this mode can be changed for 1D and 2D step modes. This mode allows the user to use he same commands as Tuning Mode.
=== Running additional Tests ===
Once you have run one test with Eris on it is unnecessary to configure the FPGA or connect to the NFS server again. This is what took much of the time in the initial setup. This is what the script ''3_stat_eris.sh'' was developed for. It does everything that ''1_co3050-11.sh'' does but without reprogramming the FPGA or reconnecting to the NFS server. As a result it is ready to test much quicker.
Before starting the test it is best to have someone spotting the pendulum a holding it near vertical so that the pendulum doesn't have issues when entering a control mode.'''<span style="color:red"> Always run ensure the pendulum is spotted by a second person when testing so you don't hurt yourself, others in the lab, or the RADA system.</span>''' Once you spotter is ready run the shell scrip by= using the command ''./3_start_eris.sh'' in the terminal with the open SSH connection to Eris from the home, ''/root'', directory of Eris.
[[Image:StartingRADA2nd.png|800px]]
=== Locating and retrieving log files ===
Once you are done with a test that you want to compare to the model you should retrieve the log file right away so you don't mix it up with other test. On CO3050-11 go to the dircetory ''/home/shared/MainProject/Logs'' using the file browser (you can do this in a terminal but it is easier from the file explorer). Once there, look for the folder that has been modified most recently as Eris date is normally out of sync with its date and time. Then look for the newest log file. Log files are named like ''log(hh.mm.ss).txt'' (ex. log(13.04.51).txt). This naming convention works well to ensure that no log file is over written but it isn't useful of describing what the test was of or for. Copy this log to the Desktop or to a USB drive and rename it. A good method is to name the file something like ''RADA_ctrl_otherNote#.txt'', where Describes what system you tested (ex. RADA, RADA1D, PEN1D, PEN2D), what typ of controller was used, other notes and then a number if this is a repeat of another test. This is much more useful when looking back at these logs later on. Before transferring the log file for processing you should record the wheel and propeller battery voltages in the header of the log file. The log file format is both human readable and can be parsed by MATALB. It was designed by the first RADA Senior Design Team and more information about the log files can be found [http://wikis.ece.iastate.edu/robotic-agriculture-data-acquisition/index.php/Data_Analysis_Tool here.] See he section below on measuring battery voltage below in order to get the best measurements for simulation of RADA.
=== Measuring battery voltages ===
The last thing that you need to do before simulating an experiment of the RADA platform is record the battery voltages for both the wheels and propellers. The wheel battery can be measured unloaded as there isn't large line losses between the battery and the H-bridges. The propeller battery voltage needs to be measured under load because the power cord running up the pendulum has significant line losses at the currents the propellers draw when in use. The battery voltages can be recorded in the log file for the test. Open the log file for the test you just completed (Use KWrite for Linux machines or Notepad++ for Windows machines). The first few lines of the log is the headder. It should look like this:
#Constants pitch_P pitch_I pitch_D
#PIDValues 48000 18000 21000
#Constants roll_P roll_I roll_D
#PIDValues 48000 18000 21000
#Battery Vquad Vwheels
#Voltage
Follow the procedure for measuring the voltage of each battery and then record the voltage under the corresponding battery. Then save the log file and close out of your text editor and the test will be ready for processing. Recoding the battery voltages in this way makes it much easier to find if you need the value latter. The final log file header should look like this once you are done
#Constants pitch_P pitch_I pitch_D
#PIDValues 48000 18000 21000
#Constants roll_P roll_I roll_D
#PIDValues 48000 18000 21000
#Battery Vquad Vwheels
#Voltage 14.44 8.257
==== Wheel Battery ====
1. After test disconnect wheel battery from the system.
2. Measure voltage of battery using multimeter.
[[Image:MeasureVwheel.jpg|800px]]
You can use the plug used for charging the 2-cell Lipos but make sure to connect the plug to the multimeter before connecting the battery and disconnect the battery before disconnecting the plug from the mulitmeter. It is generally the best practice to give the multimeter a few minutes to allow for the voltage measurement to stabilize as the battery measurement tends to be a little low right after the test.
==== Quad Battery ====
1. Setup code to run all four propellers at 50% throttle, uncomment the definition of ''mot50'' in main.cpp and compile the project.
2. Power off propellers by turning off the switch to the ESCs.
3. Connect multimeter to measure the voltage across one of the ESCs. This is done by using the power splitter cord.
-Connect one of the female XT60 connectors on the splitter to a male XT60 connector to banana connector cable.
-The banana connector connect to the hand held multimeter. The multimeter should be set to the 20VDC measurement setting.
-Next unplug one the ESCs' power connection.
-reconnect the ESC to power through the two remain connectors on the spliter cable.
4. Power on the propellers.
5. Run the system at 50% throttle and measure the steady-state voltage during the test. The battery will slow the voltage decay significantly, meaning it will keep the same measurement for a few seconds.
6. Stop the test and record the voltage in the log file. Make sure to disconnect the batter before removing the splitter cable.
{| class="wikitable" style="text-align:center"
|-
| [[Image:PowerSplitter.jpg|200px]]
| [[Image:QuadMultiCon.jpg |200px]]
| [[Image:QuadMultiSet.JPG |200px]]
| [[Image:QuadMeasESCcon.JPG|200px]]
|-
| Splitter cord.
| Connect splitter to multimeter.
| Settings for multimeter.
| Connecting ESC through splitter.
|}
The testing setup should look like the image below:
[[Image:QuadBattMeas.jpg|800px]]
== Post processing and Simulation ==
=== Using the MATLAB data parsing tool ===
=== Adding additional data for simulations ===
=== Setting up the MATLAB workspace for simulation ===
=== Running simulations and storing results ===
=== Plotting results ===
75b928c12401e94896f3814a9dbf0ca80c16aca2
259
258
2016-08-02T21:02:14Z
Pfuhing
5
/* Post processing and Simulation */
wikitext
text/x-wiki
This page will take you though setting up and testing RADA, retrieving the log file and other necessary data to run a simulation of that test and processing the data in MATLAB. Then actually running the simulation of RADA in Simulink.
== Setting Up a RADA Test ==
Testing RADA is not overly difficult once you get the hang of the steps to setup RADA. The following steps may seem like a long process to go from starting the testing process to having completed simulation and plotting of the test results but this whole test procedure (with the exception of battery charging) can be completed in about 15-20 minutes. These steps are meant to be as detailed as possible in order to help new users of RADA to get up and running as quickly as possible.
'''<span style="color:red">NOTE: Always run RADA with at least 2 people!</span>''' The pendulum arm can crash into the ground if the network starts to drop packets and one person cannot give commands to RADA and spot the pendulum. This is a safety issue for both you and the RADA platform.
=== Charging batteries ===
The lab currently uses mostly Hyperion batteries. We charge our batteries with a Hyperion EOS 1420i Net3 battery charger. For some general information about how to use this charger see [https://www.youtube.com/watch?v=-ox3EpzvsJ8 this video.]. In the lab we power this charger using the old Kepco Power supplu because it is the only power supply that we have that can supply enough current. Make sure that the power supply is set to an output voltage between 10.5V-29V.
{| class="wikitable" style="text-align:center"
|-
| [[Image:ChargerPowerSupplyOff.JPG|400px]]
| [[Image:ChargerPowerSuplyOn.JPG|400px]]
|-
| Kepco Power Supply off.
| Kepco Power Supply on with correct voltage supply range.
|}
While the YouTube video linked above should explain how to use the charger. Currently three different Lithium polymer batteries (Lipo): 1600 mAh 2-cell Lipo for the wheels, 2600 mAh 2-cell Lipo for the electronics of Eris, and a 2600 mAh 4-cell Lipo. The 1600 mAh 2-cell Lipo can be charged using memory slot 2 of the charger. The 2600 mAh 2-cell Lipos can be charged using memory slot 3 for fast charging and memory slot 4 for slower charging (use this if the battery gets run really low for 10-20 minutes then switch to fast charging). The 2600 mAh 4-cell Lipo can be charged using memory slot 8. The 1600 mAh 2-cell and 2600 mAr 4-cell generally charge in 10-20 minutes apiece while I generally fine it takes the 2600 mAh 2-cell up to 70 minutes to charge fully.
=== Setting up the camera system ===
The camera system is run on the windows computer CO3050-07. You can log into this computer using a local microcart username and password which is not posted here for security reasons but any one who works in the lab should know it. Once logged in look for Tracking Tools in the start menu or look for the shortcut shown below:
[[Image:TrackingTools_shortcut.PNG|thumb|center|Tracking Tools shortcut]]
Once the program opens the screen should look something like this:
[[Image:NewTrackingTools.PNG|800px]]
In the Tracking Tools Quick Start pop up menu select Open Existing Project and then navigate to ''D:\Optitrack_Configuration'' (It should open to this directory by default) and select the most recent Tracking Tools project. It should be named like ''TrackingToolsProject YYYY-MM-DD timeStamp.ttp''. This is normally the most recently edited file when sorting by data modified. The most recent one as of August 1st, 2016 is ''TrackingToolsProject 2015-09-23 2.30pm.ttp''.
[[Image:OpeningProject.PNG|800px]]
You should notice that the cameras shown in main project scree arrange themselves like out camera configuration once the project has been opened. Now the constellations need to be loaded. This can be done by going to ''File->Open'' and another pop up window will open. Navigate back to ''D:\Optitrack_Configuration'' (It should open to this directory by default) and select the most recently dated set of RADA trackables. They are named like ''RADA_entireSystem_M_D_YYYY.tra''. The most recent one as of August 1st, 2016 is ''RADA_entireSystem_7_8_2016.tra''.
[[Image:Opening_trackables.PNG|800px]]
Once the project and trackless are open the cameras should appear in their constellation (square) and there should be two constellations under ''Project Explorer->Trackables''. One Named UAV for the pendulum and one named ERIS for the ground vehicle. In order to get additional information about each constellation left click on the the name of the desired trackable.
[[Image:SelectingUAV.PNG|800px]]
Once a trackable is selected more information about it is available in the ''Trackables'' Tab on the right side of the screen. For the current position and orientation look at the ''Real-Time Info'' sub-tab. This gives the orientation in the wrong order for how we currently use the Euler angles. When two or three of the angles are near zero you can switch yaw and pitch to get roughly the correct orientation.
[[Image:Uav_realTimeInfo.PNG|800px]]
Now we need check to make sure the system is zeroed.
1. Hold RADA so that the front of the ground robot (ERIS is facing the wall with the white boards (east)). The front side of Eris is labeled. If it isn't it is the side opposite of the switches and the side with the trackable constellation on it.
2. Make sure that the motor with the red motor mount is also facing the wall with the white boards.
3. Make sure the quad system is aligned along Eris Axis by standing behind the system and seeing if you can use the pole to block mounting bolts of the front propeller motor mount when looking at the pole while facing the east wall.
4. While holding the pendulum approximately vertical see if the camera system reads zeros for the pendulum (UAV) pitch and roll (yaw and roll in ''Real-Time Info''). If yaw is off by a few degrees that is fine.
5. Compare the yaw of the UAV to that of ERIS (Remember this is pitch in ''Real-Time Info''). If they are both near zero and with in a few degrees and the pendulum's pitch/roll were also near zero then you are ready to use the camera system. Otherwise go to the next step.
6. You need to zero the pendulum.
- Align ERIS so it is near zero yaw first (eye ball it).
- Get a level and a friend. Have your friend use a level to ensure that the pendulum is level in both directs and hold it there.
- With the UAV constellation selected go to the ''Orientation'' tab (next to ''Real-Time Info'' tab) and click on ''Reset To Current Orientation button''
- Now your friend can set the pendulum down and you can zero ERIS the same way.
7. Save the new trackable orientation by going to ''File->Save Trakables...'' and save a file using the same naming conventions as the trackable file you opened earlier except use the current data so you don't have to re-zero the system the next time you test.
[[Image:Uav_ResetOrientation.PNG|800px]]
=== Building Software ===
The development environment for running RADA is hosted on CO3050-11, a Linux Red Hat environment. This computer has a local ucart user name that you should use. The password isn't put here for security reasons. In order to ensure that the RADA software is setup correctly for the test you want to run. To do this you will need to open the main.cpp and logger.cpp files and make sure all of the compile time macros you want are defined correctly. All of the c++ files you should need to edit are in the directory ''~/Desktop/rada_research_project/ErisResearchCode/CppProjects/MainProgram_PacketLoss/src/Korebot'' Below is a compiler macro options for main.cpp:
-'''H2ctrl''' : This will cause the system to enter H2 controller mode where the whole RADA system is controlled by an H2 controller.
-'''ssTracking''' : H2ctrl must also be defined for this macro to do anything. This macro will has the system to be controlled by a tracking H2 controller.
-'''ssMotors''' : H2ctrl must also be defined for this macro to do anything. This macro will has the system to be controlled by an H2 contorller that contains propeller states. This also cause the system to "Dance."
-'''ssDrop''' : Cause the system to go into packet drop controller mode. This mode allows controllers designed for lossy networks to be tested. Based off of other definitions how lossy the network is can be simulated. If nothing else is defined this controller becomes basically a H2 controller.
-'''drop10''' : Will put the packet drop mode into 10% loss mode and use a controller designed for 10% loss.
-'''drop30''' : Will put the packet drop mode into 30% loss mode and use a controller designed for 30% loss.
-'''drop50''' : Will put the packet drop mode into 50% loss mode and use a controller designed for 50% loss.
-'''mot50''' : This macro over-rides all other macros. If this is turned on the wheels will not run and the propllers will be run at 50% command. This is used for measuring the effective battery voltage seen by the ESCs. This is always run after a test.
-'''RADAlqi''' : This macro will cause the system to use an LQI controller on the whole system. The linear velocity states are calculated with no filter and the angular velocity states are calculated with filters.
-'''RADAlqi_est''' : This macro will cause the system to use an LQI controller on the whole system. A traditional estimator is used to estimate the states.
-'''rada_lqg''' : This macro will cause the entire system to be controlled by a LQG controller/estimator system.
-'''rada_split_lqg''' : This macro will cause the pendulum and ground robot to be controlled by their own LQG systems.
-'''rada_split_lqg_ol''' : This macro will cause the pendulum to be controlled by an LQG controller, the yaw of the ground robot to be controlled by a PID controller, and the ground robot linear velocities to be controlled with open-loop commands.
-'''yaw_off''' : This macro will cause the yaw control to be disabled on some controllers.
*'''accR''' : This macro will cause the PID linear velocity controllers to be given ramps to acclerate from one velocity to another instead of steps.
-'''posRamp''' : This macro will cause the linear velocities of RADA to be controlled by position PIDs with ramp reference instead of velocity commands.
-If no controller selection is made all controllers revert to PID controllers
All of these macros can be defined simply by uncommenting the corresponding define statement in main.cpp. The macros in the logger.cpp can be seen below:
-'''ssDrop''' : This macro puts the logger into packed drop controller mode and logs the correct values for the packet drop controllers.
-'''RADAlqi''' : This macro puts the logger into full system LQI controller logging mode.
-'''RADAlqi_est''' : This macro puts the logger into full system LQI controller plus estimator logging mode.
-'''rada_lqg''' : This puts the logger into full system LQG controller logging mode.
-'''rada_split_lqg''' : This macro causes the logger to log data about the subsystem LQG controllers.
-'''rada_split_lqg_ol''' : This cause the system to log data about the pendulum LQG system and the open-loop linear velocity commands.
-'''H2ctrl''' : This macro causes the logger to log data about the full system H2 controllers.
-If no logging mode is selected then the logger will default to logging PID data.
Because the system only calculates controllers for one set of controllers it is important to ensure that the logger is in the correct mode based off of what is defined in main.cpp. As of August 1st, 2016 the defines in main.cpp are not seen in logger.cpp.
Finally in a command prompt navigate to the driectroy: ''~/Desktop/rada_research_project/ErisResearchCode/CppProjects/MainProgram_PacketLoss''
Here just type: ''make''. The code will compile for your desired mode. For setting up a new development directory see [http://wikis.ece.iastate.edu/robotic-agriculture-data-acquisition/index.php/Setting_up_a_new_development_environment Setting up a new development environment] from the RADA senior Design wiki.
[[Image:ComplingRADACode.png|800px]]
The complied executable code ends up in ''/home/shared/MainProject''. The ''/home/shared'' directory is setup as a network file share (NFS).
[[Image:ErisCompliedCode-config.png|800px]]
This service needs to be restarted when CO3050-11 is restarted. [http://wikis.ece.iastate.edu/robotic-agriculture-data-acquisition/index.php/Configuring_NFS_shares_for_the_robot Configure NFS shares for the robot] from the RADA Senior Design wiki. Be sure to use the new Linux install command in step six. Though I have fond that even on a good strt the ''[ok]'' messages will still print.
=== Turing on RADA ===
Turing on Eris is fairly simple. Each system has its own battery. There is one for the wheels that plugs in at the front of Eris (opposite side of the swiches), one for the electronics in the back of Eris (in between the switches), and one for the propellers that goes on top of Eris.
[[Image:ErisOnPhoto.jpg|800px]]
The wheel battery is normally 1600 mAh 2-cell Lipo but any 2-cell Lipo will work. The wheels are turned on by flipping the silver switch so the top points away from the system. The electronics normally use a 2600 mAh 2-cell Lipo. The electronics are turned on by flipping the green switch away from the system. It is important that you only the WIFI adapter or Ethernet plugged in at the same time or VRPN my listen to the camera data broadcast over both connects which could cause problems. The propeller system is powered via a 2600 mAh 4-cell Lipo that connects to a power cable at the base of the pendulum. There is a switch to turn on the power to the propellers system. You will know it is on when the 1 on the switch is flush with the switch housing instead of sticking out. It takes about 30 seconds to a minute for Eris to boot up and start the networking connections. When the WIFI is plugged in you will know it is ready when a blue light turns on, on the module.
=== Connecting to RADA ===
RADA is controlled through an SSH connection. in a commands prompt, not the one you compile the code from so that you can recompile for different setup with out needing to close the connection. If you are using a WIFI connect use the command ''ssh root@192.168.0.53''. If you are connected to Eris through a LAN connaction use the command ''ssh root@192.168.0.54''. If the connection goes though you should be proped for a password.
The password is ''rootme''.
[[Image:Ssh2Eris.png|800px]]
It is important to close the SSH connection before turning off Eris because the terminal you are using will hang up if you don't. You can close the connection by using the command ''exit''.
[[Image:ClosingSSH.png|800px]]
== Testing RADA ==
Now that you are connected to Eris you can run tests. The testing is started by a few different methods.
=== Running the first test after power up ===
For the firs test after powering on Eris a few additional steps need to be completed in order to test the system. The FPGA motor controller needs to be programmed and Eris needs to connect the the NFS server running on CO3050-11. This is accomplished by running ''1_co3050-11.sh'', this shell scrip will setup the NFS, load the bit file into the FPGA configuration memory. Then it retrieves the executable file from the NFS server ''/mnt/nfs/MainProject and runs the executable. Once the user exits the executable the log file produces is copied from the ''~/Logs/YYYY_MM_DD_Day'' directory on Eris to ''/home/shared/MainProject/Logs/YYYY_MM_DD_Day'' on CO3050-11. When the folder for the current Eris date doesn't exist it creates this directory in CO3050-11 and then removes the directory and log file from Eris. You may see an warning that when coping the log file Eris couldn't maintain the file permisiion settings. This is normal as Eris doesn't have the same access to the NSF server as it has to its own files. This Date stamp uses date on Eris which is currently in June of 2008 as of August 2nd, 2016.
Before starting the test it is best to have someone spotting the pendulum a holding it near vertical so that the pendulum doesn't have issues when entering a control mode.'''<span style="color:red"> Always run ensure the pendulum is spotted by a second person when testing so you don't hurt yourself, others in the lab, or the RADA system.</span>''' Once you spotter is ready run the shell scrip by= using the command ''./1_co3050-11.sh'' in the terminal with the open SSH connection to Eris from the home, ''/root'', directory of Eris. When you run this script there will be a bunch of information printed out about the PIC bus and loading the bit file to configure the FPGA, you will know that RADA is ready for the test when it asks you to select a running mode. See the Testing Modes section below. This script can take a while to complete so beyond the first test after start up you don't need to run this script. See the Section about Running additional tests below.
[[Image:StartingRADA initial.png|800px]]
=== Testing Modes ===
The RADA system has three testing modes: Robot Control Mode, Tuning Mode, and Box Step Mode. Additionally you can exit the execution at any time by pressing the ''Esc'' key. Once the terminal asks you to chose a mode you can use the following commands to enter the desired mode with a three second delay or exit the program. You can also use these commands to switch between the modes.
-''v'' : Enters the pendulum PID tuning mode, this will only really work when using PIDs to control the pendulum.
-''b'' : Enter Robot control mode, in this mode you can drive the robot around and the pendulum will try to stay vertical. This is the main mode used for testing the whole RADA system.
-''n'' : Enters box step mode, where the pendulum will change its desired pitch and roll angles every 20 seconds and move in a box shape.
-''Esc'' : By hitting the escape key the program will exit the program.
You will almost always want to run Robot Control Mode as the other modes are legacy modes from when we initially built and tested RADA and only works with the pendulum PID controllers. There are also a few utility commands that can be used in all modes.
-''2'' : Resets I composts of the Pitch/Roll PIDs and only the PIDs.
-''m'' : Adds a marker to the Log file incase odd things happen somewhere. This just increments a counter so if you use it look for changes in the marker value.
==== Robot Control Model ====
In Robot control mode you can control the motion of Eris. For PID control of Eris or 1D state feedback system the directional commands command Eris body velocity were for full system and Eris system state feedback controllers control the global velocity. All of these keys only need to be pressed not held down.
-''w'' : Moves Eris forward (+x) at some velocity depending on the controller.
-''s'' : Moves Eris in reverse (-x) at some velocity depending on the controller.
-''d'' : Moves Eris in right (+y) at some velocity depending on the controller.
-''a'' : Moves Eris in left (-y) at some velocity depending on the controller.
-''p'' : Stops the motion of Eris (Set all velocity set points to zero). I.e. if you hit ''w'' then hit ''s'' then Eris will be moving in reverse.
-''y'' : Moves Eris forward and to the right (+x/+y) simultaneously at some velocity depending on the controller.
-''t'' : Moves Eris forward and to the left (+x/-y) simultaneously at some velocity depending on the controller.
-''i'' : Moves Eris reverse and to the right (-x/+y) simultaneously at some velocity depending on the controller.
-''y'' : Moves Eris reverse and to the left (-x/-y) simultaneously at some velocity depending on the controller.
-''e'' : Rotate Eris clockwise (+yaw) at some angular rate. This only worked when RADA used the closed-loop FPGA control of the wheels. There is currently no controllers that use this command.
-''q'' : Rotate Eris counter-clockwise (-yaw) at some angular rate. This only worked when RADA used the closed-loop FPGA control of the wheels. There is currently no controllers that use this command.
-''<'' : Increment Eris' desired heading 45 degrees counter-clockwise (-yaw).
-''>'' : Increment Eris' desired heading 45 degrees clockwise (+yaw).
-''7'' : Increments the pitch set point (+pitch).
-''4'' : Decrements the pitch set point (-pitch).
-''8'' : Increments the roll set point (+roll).
-''5'' : Decrements the roll set point (-roll).
==== Tuning Mode ====
Tuning mode allows you to tune the PID controllers for both pitch and roll. The UI commands here are also available in Box Step Mode.
-''1'' : Tune the Pitch PID.
-''3'' : Tune the Roll PID.
-''7'' : Increase proportional gain of PID being tuned.
-''4'' : Decrease proportional gain of PID being tuned.
-''8'' : Increase integral gain of PID being tuned.
-''5'' : Decrease integral gain of PID being tuned.
-''9'' : Increase derivative gain of PID being tuned.
-''6'' : Decrease derivative gain of PID being tuned.
-''i'' : Increase set point of PID being tuned.
-''k'' : Decrease set point of PID being tuned.
-''o'' : Increase integral windup term of PID being tuned. (Not used)
-''l'' : Decrease integral windup term of PID being tuned. (Not used)
==== Box Step Mode ====
Box set mode will automatically change the set points of the pendulum every 20 seconds. The case statement for this mode can be changed for 1D and 2D step modes. This mode allows the user to use he same commands as Tuning Mode.
=== Running additional Tests ===
Once you have run one test with Eris on it is unnecessary to configure the FPGA or connect to the NFS server again. This is what took much of the time in the initial setup. This is what the script ''3_stat_eris.sh'' was developed for. It does everything that ''1_co3050-11.sh'' does but without reprogramming the FPGA or reconnecting to the NFS server. As a result it is ready to test much quicker.
Before starting the test it is best to have someone spotting the pendulum a holding it near vertical so that the pendulum doesn't have issues when entering a control mode.'''<span style="color:red"> Always run ensure the pendulum is spotted by a second person when testing so you don't hurt yourself, others in the lab, or the RADA system.</span>''' Once you spotter is ready run the shell scrip by= using the command ''./3_start_eris.sh'' in the terminal with the open SSH connection to Eris from the home, ''/root'', directory of Eris.
[[Image:StartingRADA2nd.png|800px]]
=== Locating and retrieving log files ===
Once you are done with a test that you want to compare to the model you should retrieve the log file right away so you don't mix it up with other test. On CO3050-11 go to the dircetory ''/home/shared/MainProject/Logs'' using the file browser (you can do this in a terminal but it is easier from the file explorer). Once there, look for the folder that has been modified most recently as Eris date is normally out of sync with its date and time. Then look for the newest log file. Log files are named like ''log(hh.mm.ss).txt'' (ex. log(13.04.51).txt). This naming convention works well to ensure that no log file is over written but it isn't useful of describing what the test was of or for. Copy this log to the Desktop or to a USB drive and rename it. A good method is to name the file something like ''RADA_ctrl_otherNote#.txt'', where Describes what system you tested (ex. RADA, RADA1D, PEN1D, PEN2D), what typ of controller was used, other notes and then a number if this is a repeat of another test. This is much more useful when looking back at these logs later on. Before transferring the log file for processing you should record the wheel and propeller battery voltages in the header of the log file. The log file format is both human readable and can be parsed by MATALB. It was designed by the first RADA Senior Design Team and more information about the log files can be found [http://wikis.ece.iastate.edu/robotic-agriculture-data-acquisition/index.php/Data_Analysis_Tool here.] See he section below on measuring battery voltage below in order to get the best measurements for simulation of RADA.
=== Measuring battery voltages ===
The last thing that you need to do before simulating an experiment of the RADA platform is record the battery voltages for both the wheels and propellers. The wheel battery can be measured unloaded as there isn't large line losses between the battery and the H-bridges. The propeller battery voltage needs to be measured under load because the power cord running up the pendulum has significant line losses at the currents the propellers draw when in use. The battery voltages can be recorded in the log file for the test. Open the log file for the test you just completed (Use KWrite for Linux machines or Notepad++ for Windows machines). The first few lines of the log is the headder. It should look like this:
#Constants pitch_P pitch_I pitch_D
#PIDValues 48000 18000 21000
#Constants roll_P roll_I roll_D
#PIDValues 48000 18000 21000
#Battery Vquad Vwheels
#Voltage
Follow the procedure for measuring the voltage of each battery and then record the voltage under the corresponding battery. Then save the log file and close out of your text editor and the test will be ready for processing. Recoding the battery voltages in this way makes it much easier to find if you need the value latter. The final log file header should look like this once you are done
#Constants pitch_P pitch_I pitch_D
#PIDValues 48000 18000 21000
#Constants roll_P roll_I roll_D
#PIDValues 48000 18000 21000
#Battery Vquad Vwheels
#Voltage 14.44 8.257
==== Wheel Battery ====
1. After test disconnect wheel battery from the system.
2. Measure voltage of battery using multimeter.
[[Image:MeasureVwheel.jpg|800px]]
You can use the plug used for charging the 2-cell Lipos but make sure to connect the plug to the multimeter before connecting the battery and disconnect the battery before disconnecting the plug from the mulitmeter. It is generally the best practice to give the multimeter a few minutes to allow for the voltage measurement to stabilize as the battery measurement tends to be a little low right after the test.
==== Quad Battery ====
1. Setup code to run all four propellers at 50% throttle, uncomment the definition of ''mot50'' in main.cpp and compile the project.
2. Power off propellers by turning off the switch to the ESCs.
3. Connect multimeter to measure the voltage across one of the ESCs. This is done by using the power splitter cord.
-Connect one of the female XT60 connectors on the splitter to a male XT60 connector to banana connector cable.
-The banana connector connect to the hand held multimeter. The multimeter should be set to the 20VDC measurement setting.
-Next unplug one the ESCs' power connection.
-reconnect the ESC to power through the two remain connectors on the spliter cable.
4. Power on the propellers.
5. Run the system at 50% throttle and measure the steady-state voltage during the test. The battery will slow the voltage decay significantly, meaning it will keep the same measurement for a few seconds.
6. Stop the test and record the voltage in the log file. Make sure to disconnect the batter before removing the splitter cable.
{| class="wikitable" style="text-align:center"
|-
| [[Image:PowerSplitter.jpg|200px]]
| [[Image:QuadMultiCon.jpg |200px]]
| [[Image:QuadMultiSet.JPG |200px]]
| [[Image:QuadMeasESCcon.JPG|200px]]
|-
| Splitter cord.
| Connect splitter to multimeter.
| Settings for multimeter.
| Connecting ESC through splitter.
|}
The testing setup should look like the image below:
[[Image:QuadBattMeas.jpg|800px]]
== Post processing and Simulation ==
Simulating a test of RADA starts with processing and storing the data. Then all of the parameters of the model are loaded in the MATLAB Workspace. Finally the Simulink file used for the simulation is opened and the length of the simulation is set to match the length of the actual test. The simulation is run and the simulation output is stored. Finally the data should be plotted and compared.
=== Using the MATLAB data parsing tool ===
In depth discussion of how to use the log file parsing tool is described
=== Adding additional data for simulations ===
=== Setting up the MATLAB workspace for simulation ===
=== Running simulations and storing results ===
=== Plotting results ===
787010c4f2fa74d9cba33fb619594f6450f212de
260
259
2016-08-02T22:16:44Z
Pfuhing
5
wikitext
text/x-wiki
This page will take you though setting up and testing RADA, retrieving the log file and other necessary data to run a simulation of that test and processing the data in MATLAB. Then actually running the simulation of RADA in Simulink. The initial setup and how to test the system can also be applied to demoing RADA.
== Setting Up a RADA Test ==
Testing RADA is not overly difficult once you get the hang of the steps to setup RADA. The following steps may seem like a long process to go from starting the testing process to having completed simulation and plotting of the test results but this whole test procedure (with the exception of battery charging) can be completed in about 15-20 minutes. These steps are meant to be as detailed as possible in order to help new users of RADA to get up and running as quickly as possible.
'''<span style="color:red">NOTE: Always run RADA with at least 2 people!</span>''' The pendulum arm can crash into the ground if the network starts to drop packets and one person cannot give commands to RADA and spot the pendulum. This is a safety issue for both you and the RADA platform.
=== Charging batteries ===
The lab currently uses mostly Hyperion batteries. We charge our batteries with a Hyperion EOS 1420i Net3 battery charger. For some general information about how to use this charger see [https://www.youtube.com/watch?v=-ox3EpzvsJ8 this video.]. In the lab we power this charger using the old Kepco Power supplu because it is the only power supply that we have that can supply enough current. Make sure that the power supply is set to an output voltage between 10.5V-29V.
{| class="wikitable" style="text-align:center"
|-
| [[Image:ChargerPowerSupplyOff.JPG|400px]]
| [[Image:ChargerPowerSuplyOn.JPG|400px]]
|-
| Kepco Power Supply off.
| Kepco Power Supply on with correct voltage supply range.
|}
While the YouTube video linked above should explain how to use the charger. Currently three different Lithium polymer batteries (Lipo): 1600 mAh 2-cell Lipo for the wheels, 2600 mAh 2-cell Lipo for the electronics of Eris, and a 2600 mAh 4-cell Lipo. The 1600 mAh 2-cell Lipo can be charged using memory slot 2 of the charger. The 2600 mAh 2-cell Lipos can be charged using memory slot 3 for fast charging and memory slot 4 for slower charging (use this if the battery gets run really low for 10-20 minutes then switch to fast charging). The 2600 mAh 4-cell Lipo can be charged using memory slot 8. The 1600 mAh 2-cell and 2600 mAr 4-cell generally charge in 10-20 minutes apiece while I generally fine it takes the 2600 mAh 2-cell up to 70 minutes to charge fully.
=== Setting up the camera system ===
The camera system is run on the windows computer CO3050-07. You can log into this computer using a local microcart username and password which is not posted here for security reasons but any one who works in the lab should know it. Once logged in look for Tracking Tools in the start menu or look for the shortcut shown below:
[[Image:TrackingTools_shortcut.PNG|thumb|center|Tracking Tools shortcut]]
Once the program opens the screen should look something like this:
[[Image:NewTrackingTools.PNG|800px]]
In the Tracking Tools Quick Start pop up menu select Open Existing Project and then navigate to ''D:\Optitrack_Configuration'' (It should open to this directory by default) and select the most recent Tracking Tools project. It should be named like ''TrackingToolsProject YYYY-MM-DD timeStamp.ttp''. This is normally the most recently edited file when sorting by data modified. The most recent one as of August 1st, 2016 is ''TrackingToolsProject 2015-09-23 2.30pm.ttp''.
[[Image:OpeningProject.PNG|800px]]
You should notice that the cameras shown in main project scree arrange themselves like out camera configuration once the project has been opened. Now the constellations need to be loaded. This can be done by going to ''File->Open'' and another pop up window will open. Navigate back to ''D:\Optitrack_Configuration'' (It should open to this directory by default) and select the most recently dated set of RADA trackables. They are named like ''RADA_entireSystem_M_D_YYYY.tra''. The most recent one as of August 1st, 2016 is ''RADA_entireSystem_7_8_2016.tra''.
[[Image:Opening_trackables.PNG|800px]]
Once the project and trackless are open the cameras should appear in their constellation (square) and there should be two constellations under ''Project Explorer->Trackables''. One Named UAV for the pendulum and one named ERIS for the ground vehicle. In order to get additional information about each constellation left click on the the name of the desired trackable.
[[Image:SelectingUAV.PNG|800px]]
Once a trackable is selected more information about it is available in the ''Trackables'' Tab on the right side of the screen. For the current position and orientation look at the ''Real-Time Info'' sub-tab. This gives the orientation in the wrong order for how we currently use the Euler angles. When two or three of the angles are near zero you can switch yaw and pitch to get roughly the correct orientation.
[[Image:Uav_realTimeInfo.PNG|800px]]
Now we need check to make sure the system is zeroed.
1. Hold RADA so that the front of the ground robot (ERIS is facing the wall with the white boards (east)). The front side of Eris is labeled. If it isn't it is the side opposite of the switches and the side with the trackable constellation on it.
2. Make sure that the motor with the red motor mount is also facing the wall with the white boards.
3. Make sure the quad system is aligned along Eris Axis by standing behind the system and seeing if you can use the pole to block mounting bolts of the front propeller motor mount when looking at the pole while facing the east wall.
4. While holding the pendulum approximately vertical see if the camera system reads zeros for the pendulum (UAV) pitch and roll (yaw and roll in ''Real-Time Info''). If yaw is off by a few degrees that is fine.
5. Compare the yaw of the UAV to that of ERIS (Remember this is pitch in ''Real-Time Info''). If they are both near zero and with in a few degrees and the pendulum's pitch/roll were also near zero then you are ready to use the camera system. Otherwise go to the next step.
6. You need to zero the pendulum.
- Align ERIS so it is near zero yaw first (eye ball it).
- Get a level and a friend. Have your friend use a level to ensure that the pendulum is level in both directs and hold it there.
- With the UAV constellation selected go to the ''Orientation'' tab (next to ''Real-Time Info'' tab) and click on ''Reset To Current Orientation button''
- Now your friend can set the pendulum down and you can zero ERIS the same way.
7. Save the new trackable orientation by going to ''File->Save Trakables...'' and save a file using the same naming conventions as the trackable file you opened earlier except use the current data so you don't have to re-zero the system the next time you test.
[[Image:Uav_ResetOrientation.PNG|800px]]
=== Building Software ===
The development environment for running RADA is hosted on CO3050-11, a Linux Red Hat environment. This computer has a local ucart user name that you should use. The password isn't put here for security reasons. In order to ensure that the RADA software is setup correctly for the test you want to run. To do this you will need to open the main.cpp and logger.cpp files and make sure all of the compile time macros you want are defined correctly. All of the c++ files you should need to edit are in the directory ''~/Desktop/rada_research_project/ErisResearchCode/CppProjects/MainProgram_PacketLoss/src/Korebot'' Below is a compiler macro options for main.cpp:
-'''H2ctrl''' : This will cause the system to enter H2 controller mode where the whole RADA system is controlled by an H2 controller.
-'''ssTracking''' : H2ctrl must also be defined for this macro to do anything. This macro will has the system to be controlled by a tracking H2 controller.
-'''ssMotors''' : H2ctrl must also be defined for this macro to do anything. This macro will has the system to be controlled by an H2 contorller that contains propeller states. This also cause the system to "Dance."
-'''ssDrop''' : Cause the system to go into packet drop controller mode. This mode allows controllers designed for lossy networks to be tested. Based off of other definitions how lossy the network is can be simulated. If nothing else is defined this controller becomes basically a H2 controller.
-'''drop10''' : Will put the packet drop mode into 10% loss mode and use a controller designed for 10% loss.
-'''drop30''' : Will put the packet drop mode into 30% loss mode and use a controller designed for 30% loss.
-'''drop50''' : Will put the packet drop mode into 50% loss mode and use a controller designed for 50% loss.
-'''mot50''' : This macro over-rides all other macros. If this is turned on the wheels will not run and the propllers will be run at 50% command. This is used for measuring the effective battery voltage seen by the ESCs. This is always run after a test.
-'''RADAlqi''' : This macro will cause the system to use an LQI controller on the whole system. The linear velocity states are calculated with no filter and the angular velocity states are calculated with filters.
-'''RADAlqi_est''' : This macro will cause the system to use an LQI controller on the whole system. A traditional estimator is used to estimate the states.
-'''rada_lqg''' : This macro will cause the entire system to be controlled by a LQG controller/estimator system.
-'''rada_split_lqg''' : This macro will cause the pendulum and ground robot to be controlled by their own LQG systems.
-'''rada_split_lqg_ol''' : This macro will cause the pendulum to be controlled by an LQG controller, the yaw of the ground robot to be controlled by a PID controller, and the ground robot linear velocities to be controlled with open-loop commands.
-'''yaw_off''' : This macro will cause the yaw control to be disabled on some controllers.
*'''accR''' : This macro will cause the PID linear velocity controllers to be given ramps to acclerate from one velocity to another instead of steps.
-'''posRamp''' : This macro will cause the linear velocities of RADA to be controlled by position PIDs with ramp reference instead of velocity commands.
-If no controller selection is made all controllers revert to PID controllers
All of these macros can be defined simply by uncommenting the corresponding define statement in main.cpp. The macros in the logger.cpp can be seen below:
-'''ssDrop''' : This macro puts the logger into packed drop controller mode and logs the correct values for the packet drop controllers.
-'''RADAlqi''' : This macro puts the logger into full system LQI controller logging mode.
-'''RADAlqi_est''' : This macro puts the logger into full system LQI controller plus estimator logging mode.
-'''rada_lqg''' : This puts the logger into full system LQG controller logging mode.
-'''rada_split_lqg''' : This macro causes the logger to log data about the subsystem LQG controllers.
-'''rada_split_lqg_ol''' : This cause the system to log data about the pendulum LQG system and the open-loop linear velocity commands.
-'''H2ctrl''' : This macro causes the logger to log data about the full system H2 controllers.
-If no logging mode is selected then the logger will default to logging PID data.
Because the system only calculates controllers for one set of controllers it is important to ensure that the logger is in the correct mode based off of what is defined in main.cpp. As of August 1st, 2016 the defines in main.cpp are not seen in logger.cpp.
Finally in a command prompt navigate to the driectroy: ''~/Desktop/rada_research_project/ErisResearchCode/CppProjects/MainProgram_PacketLoss''
Here just type: ''make''. The code will compile for your desired mode. For setting up a new development directory see [http://wikis.ece.iastate.edu/robotic-agriculture-data-acquisition/index.php/Setting_up_a_new_development_environment Setting up a new development environment] from the RADA senior Design wiki.
[[Image:ComplingRADACode.png|800px]]
The complied executable code ends up in ''/home/shared/MainProject''. The ''/home/shared'' directory is setup as a network file share (NFS).
[[Image:ErisCompliedCode-config.png|800px]]
This service needs to be restarted when CO3050-11 is restarted. [http://wikis.ece.iastate.edu/robotic-agriculture-data-acquisition/index.php/Configuring_NFS_shares_for_the_robot Configure NFS shares for the robot] from the RADA Senior Design wiki. Be sure to use the new Linux install command in step six. Though I have fond that even on a good strt the ''[ok]'' messages will still print.
=== Turing on RADA ===
Turing on Eris is fairly simple. Each system has its own battery. There is one for the wheels that plugs in at the front of Eris (opposite side of the swiches), one for the electronics in the back of Eris (in between the switches), and one for the propellers that goes on top of Eris.
[[Image:ErisOnPhoto.jpg|800px]]
The wheel battery is normally 1600 mAh 2-cell Lipo but any 2-cell Lipo will work. The wheels are turned on by flipping the silver switch so the top points away from the system. The electronics normally use a 2600 mAh 2-cell Lipo. The electronics are turned on by flipping the green switch away from the system. It is important that you only the WIFI adapter or Ethernet plugged in at the same time or VRPN my listen to the camera data broadcast over both connects which could cause problems. The propeller system is powered via a 2600 mAh 4-cell Lipo that connects to a power cable at the base of the pendulum. There is a switch to turn on the power to the propellers system. You will know it is on when the 1 on the switch is flush with the switch housing instead of sticking out. It takes about 30 seconds to a minute for Eris to boot up and start the networking connections. When the WIFI is plugged in you will know it is ready when a blue light turns on, on the module.
=== Connecting to RADA ===
RADA is controlled through an SSH connection. in a commands prompt, not the one you compile the code from so that you can recompile for different setup with out needing to close the connection. If you are using a WIFI connect use the command ''ssh root@192.168.0.53''. If you are connected to Eris through a LAN connaction use the command ''ssh root@192.168.0.54''. If the connection goes though you should be proped for a password.
The password is ''rootme''.
[[Image:Ssh2Eris.png|800px]]
It is important to close the SSH connection before turning off Eris because the terminal you are using will hang up if you don't. You can close the connection by using the command ''exit''.
[[Image:ClosingSSH.png|800px]]
== Testing RADA ==
Now that you are connected to Eris you can run tests. The testing is started by a few different methods.
=== Running the first test after power up ===
For the firs test after powering on Eris a few additional steps need to be completed in order to test the system. The FPGA motor controller needs to be programmed and Eris needs to connect the the NFS server running on CO3050-11. This is accomplished by running ''1_co3050-11.sh'', this shell scrip will setup the NFS, load the bit file into the FPGA configuration memory. Then it retrieves the executable file from the NFS server ''/mnt/nfs/MainProject and runs the executable. Once the user exits the executable the log file produces is copied from the ''~/Logs/YYYY_MM_DD_Day'' directory on Eris to ''/home/shared/MainProject/Logs/YYYY_MM_DD_Day'' on CO3050-11. When the folder for the current Eris date doesn't exist it creates this directory in CO3050-11 and then removes the directory and log file from Eris. You may see an warning that when coping the log file Eris couldn't maintain the file permisiion settings. This is normal as Eris doesn't have the same access to the NSF server as it has to its own files. This Date stamp uses date on Eris which is currently in June of 2008 as of August 2nd, 2016.
Before starting the test it is best to have someone spotting the pendulum a holding it near vertical so that the pendulum doesn't have issues when entering a control mode.'''<span style="color:red"> Always run ensure the pendulum is spotted by a second person when testing so you don't hurt yourself, others in the lab, or the RADA system.</span>''' Once you spotter is ready run the shell scrip by= using the command ''./1_co3050-11.sh'' in the terminal with the open SSH connection to Eris from the home, ''/root'', directory of Eris. When you run this script there will be a bunch of information printed out about the PIC bus and loading the bit file to configure the FPGA, you will know that RADA is ready for the test when it asks you to select a running mode. See the Testing Modes section below. This script can take a while to complete so beyond the first test after start up you don't need to run this script. See the Section about Running additional tests below.
[[Image:StartingRADA initial.png|800px]]
=== Testing Modes ===
The RADA system has three testing modes: Robot Control Mode, Tuning Mode, and Box Step Mode. Additionally you can exit the execution at any time by pressing the ''Esc'' key. Once the terminal asks you to chose a mode you can use the following commands to enter the desired mode with a three second delay or exit the program. You can also use these commands to switch between the modes.
-''v'' : Enters the pendulum PID tuning mode, this will only really work when using PIDs to control the pendulum.
-''b'' : Enter Robot control mode, in this mode you can drive the robot around and the pendulum will try to stay vertical. This is the main mode used for testing the whole RADA system.
-''n'' : Enters box step mode, where the pendulum will change its desired pitch and roll angles every 20 seconds and move in a box shape.
-''Esc'' : By hitting the escape key the program will exit the program.
You will almost always want to run Robot Control Mode as the other modes are legacy modes from when we initially built and tested RADA and only works with the pendulum PID controllers. There are also a few utility commands that can be used in all modes.
-''2'' : Resets I composts of the Pitch/Roll PIDs and only the PIDs.
-''m'' : Adds a marker to the Log file incase odd things happen somewhere. This just increments a counter so if you use it look for changes in the marker value.
==== Robot Control Model ====
In Robot control mode you can control the motion of Eris. For PID control of Eris or 1D state feedback system the directional commands command Eris body velocity were for full system and Eris system state feedback controllers control the global velocity. All of these keys only need to be pressed not held down.
-''w'' : Moves Eris forward (+x) at some velocity depending on the controller.
-''s'' : Moves Eris in reverse (-x) at some velocity depending on the controller.
-''d'' : Moves Eris in right (+y) at some velocity depending on the controller.
-''a'' : Moves Eris in left (-y) at some velocity depending on the controller.
-''p'' : Stops the motion of Eris (Set all velocity set points to zero). I.e. if you hit ''w'' then hit ''s'' then Eris will be moving in reverse.
-''y'' : Moves Eris forward and to the right (+x/+y) simultaneously at some velocity depending on the controller.
-''t'' : Moves Eris forward and to the left (+x/-y) simultaneously at some velocity depending on the controller.
-''i'' : Moves Eris reverse and to the right (-x/+y) simultaneously at some velocity depending on the controller.
-''y'' : Moves Eris reverse and to the left (-x/-y) simultaneously at some velocity depending on the controller.
-''e'' : Rotate Eris clockwise (+yaw) at some angular rate. This only worked when RADA used the closed-loop FPGA control of the wheels. There is currently no controllers that use this command.
-''q'' : Rotate Eris counter-clockwise (-yaw) at some angular rate. This only worked when RADA used the closed-loop FPGA control of the wheels. There is currently no controllers that use this command.
-''<'' : Increment Eris' desired heading 45 degrees counter-clockwise (-yaw).
-''>'' : Increment Eris' desired heading 45 degrees clockwise (+yaw).
-''7'' : Increments the pitch set point (+pitch).
-''4'' : Decrements the pitch set point (-pitch).
-''8'' : Increments the roll set point (+roll).
-''5'' : Decrements the roll set point (-roll).
==== Tuning Mode ====
Tuning mode allows you to tune the PID controllers for both pitch and roll. The UI commands here are also available in Box Step Mode.
-''1'' : Tune the Pitch PID.
-''3'' : Tune the Roll PID.
-''7'' : Increase proportional gain of PID being tuned.
-''4'' : Decrease proportional gain of PID being tuned.
-''8'' : Increase integral gain of PID being tuned.
-''5'' : Decrease integral gain of PID being tuned.
-''9'' : Increase derivative gain of PID being tuned.
-''6'' : Decrease derivative gain of PID being tuned.
-''i'' : Increase set point of PID being tuned.
-''k'' : Decrease set point of PID being tuned.
-''o'' : Increase integral windup term of PID being tuned. (Not used)
-''l'' : Decrease integral windup term of PID being tuned. (Not used)
==== Box Step Mode ====
Box set mode will automatically change the set points of the pendulum every 20 seconds. The case statement for this mode can be changed for 1D and 2D step modes. This mode allows the user to use he same commands as Tuning Mode.
=== Running additional Tests ===
Once you have run one test with Eris on it is unnecessary to configure the FPGA or connect to the NFS server again. This is what took much of the time in the initial setup. This is what the script ''3_stat_eris.sh'' was developed for. It does everything that ''1_co3050-11.sh'' does but without reprogramming the FPGA or reconnecting to the NFS server. As a result it is ready to test much quicker.
Before starting the test it is best to have someone spotting the pendulum a holding it near vertical so that the pendulum doesn't have issues when entering a control mode.'''<span style="color:red"> Always run ensure the pendulum is spotted by a second person when testing so you don't hurt yourself, others in the lab, or the RADA system.</span>''' Once you spotter is ready run the shell scrip by= using the command ''./3_start_eris.sh'' in the terminal with the open SSH connection to Eris from the home, ''/root'', directory of Eris.
[[Image:StartingRADA2nd.png|800px]]
=== Locating and retrieving log files ===
If you are only demoing the system there is no need to go beyond this point. Once you are done with a test that you want to compare to the model you should retrieve the log file right away so you don't mix it up with other test. On CO3050-11 go to the dircetory ''/home/shared/MainProject/Logs'' using the file browser (you can do this in a terminal but it is easier from the file explorer). Once there, look for the folder that has been modified most recently as Eris date is normally out of sync with its date and time. Then look for the newest log file. Log files are named like ''log(hh.mm.ss).txt'' (ex. log(13.04.51).txt). This naming convention works well to ensure that no log file is over written but it isn't useful of describing what the test was of or for. Copy this log to the Desktop or to a USB drive and rename it. A good method is to name the file something like ''RADA_ctrl_otherNote#.txt'', where Describes what system you tested (ex. RADA, RADA1D, PEN1D, PEN2D), what typ of controller was used, other notes and then a number if this is a repeat of another test. This is much more useful when looking back at these logs later on. Before transferring the log file for processing you should record the wheel and propeller battery voltages in the header of the log file. The log file format is both human readable and can be parsed by MATALB. It was designed by the first RADA Senior Design Team and more information about the log files can be found [http://wikis.ece.iastate.edu/robotic-agriculture-data-acquisition/index.php/Data_Analysis_Tool here.] See he section below on measuring battery voltage below in order to get the best measurements for simulation of RADA.
=== Measuring battery voltages ===
The last thing that you need to do before simulating an experiment of the RADA platform is record the battery voltages for both the wheels and propellers. The wheel battery can be measured unloaded as there isn't large line losses between the battery and the H-bridges. The propeller battery voltage needs to be measured under load because the power cord running up the pendulum has significant line losses at the currents the propellers draw when in use. The battery voltages can be recorded in the log file for the test. Open the log file for the test you just completed (Use KWrite for Linux machines or Notepad++ for Windows machines). The first few lines of the log is the headder. It should look like this:
#Constants pitch_P pitch_I pitch_D
#PIDValues 48000 18000 21000
#Constants roll_P roll_I roll_D
#PIDValues 48000 18000 21000
#Battery Vquad Vwheels
#Voltage
Follow the procedure for measuring the voltage of each battery and then record the voltage under the corresponding battery. Then save the log file and close out of your text editor and the test will be ready for processing. Recoding the battery voltages in this way makes it much easier to find if you need the value latter. The final log file header should look like this once you are done
#Constants pitch_P pitch_I pitch_D
#PIDValues 48000 18000 21000
#Constants roll_P roll_I roll_D
#PIDValues 48000 18000 21000
#Battery Vquad Vwheels
#Voltage 14.44 8.257
==== Wheel Battery ====
1. After test disconnect wheel battery from the system.
2. Measure voltage of battery using multimeter.
[[Image:MeasureVwheel.jpg|800px]]
You can use the plug used for charging the 2-cell Lipos but make sure to connect the plug to the multimeter before connecting the battery and disconnect the battery before disconnecting the plug from the mulitmeter. It is generally the best practice to give the multimeter a few minutes to allow for the voltage measurement to stabilize as the battery measurement tends to be a little low right after the test. The multimeter will report data out to four decimal places it is best just to round to three decimal places for the wheel voltage.
==== Quad Battery ====
1. Setup code to run all four propellers at 50% throttle, uncomment the definition of ''mot50'' in main.cpp and compile the project.
2. Power off propellers by turning off the switch to the ESCs.
3. Connect multimeter to measure the voltage across one of the ESCs. This is done by using the power splitter cord.
-Connect one of the female XT60 connectors on the splitter to a male XT60 connector to banana connector cable.
-The banana connector connect to the hand held multimeter. The multimeter should be set to the 20VDC measurement setting.
-Next unplug one the ESCs' power connection.
-reconnect the ESC to power through the two remain connectors on the spliter cable.
4. Power on the propellers.
5. Run the system at 50% throttle and measure the steady-state voltage during the test. The battery will slow the voltage decay significantly, meaning it will keep the same measurement for a few seconds.
6. Stop the test and record the voltage in the log file. Make sure to disconnect the batter before removing the splitter cable.
{| class="wikitable" style="text-align:center"
|-
| [[Image:PowerSplitter.jpg|200px]]
| [[Image:QuadMultiCon.jpg |200px]]
| [[Image:QuadMultiSet.JPG |200px]]
| [[Image:QuadMeasESCcon.JPG|200px]]
|-
| Splitter cord.
| Connect splitter to multimeter.
| Settings for multimeter.
| Connecting ESC through splitter.
|}
The testing setup should look like the image below:
[[Image:QuadBattMeas.jpg|800px]]
== Post processing and Simulation ==
Simulating a test of RADA starts with processing and storing the data. Then all of the parameters of the model are loaded in the MATLAB Workspace. Finally the Simulink file used for the simulation is opened and the length of the simulation is set to match the length of the actual test. The simulation is run and the simulation output is stored. Finally the data should be plotted and compared.
=== Using the MATLAB data parsing tool ===
In depth discussion of how to use the log file parsing tool is described [http://wikis.ece.iastate.edu/robotic-agriculture-data-acquisition/index.php/Data_Analysis_Tool here.] I suggest using the version of the tool in the rada_resarch_project git repository Paul Uhing used for his Master's research. It con be found on CO3050-11 under the ucart account in the directory ''~/rada_research_project/DataAnalysiTool_omnicoor/Tool''. Simply open MATLAB and set the working directory to this file path. In the MATLAB Command Prompt run ''DataAnalysis''. A popup window should open up. Select the log file you want to process and wait for the tool to finish processing the file. Once this is complete there should be four structures in the MATLAB workspace.
-'''main''' : This contains all of the data extracted from the log file and the processing parameters used. main.expData contains two time structures: Time is used for the pendulum data and Eris_time is used for the ground vehicle data.
-'''X_ref''' : This contains the reference vector in m/s for x velocity that is feed into Simulink. This expedites the simulation setup process, this used to be done by hand.
-'''Y_ref''' : This contains the reference vector in m/s for y velocity that is feed into Simulink. This expedites the simulation setup process, this used to be done by hand.
-'''Yaw_ref''' : This contains the reference vector in radians for yaw that is feed into Simulink. This expedites the simulation setup process, this used to be done by hand. This one is new incase people start testing the system with heading changes but is not used in the current setup.
The first thing you should do is rename the main structure to the name you used for the log file. This is helpful for comparing multiple tests. Next you will want to crate two new variable ''Vquad_test'' an Vw_test''. In the MATLAB Command Prompt set the measured propeller voltage from the log file to ''Vquad_test'' and set the measured the wheel voltage to ''Vw_test'' as this will be used by the simulation. Finally if you did an open-loop test of the wheels create the variable ''Uol'' and set it to the open-loop wheel command used. Save all of these variables from the MATLAB workspace to a ''.mat'' file of the same name as log file you extracted the data from and save it in the same directory as your RADA Simulink files. As of August 2nd, 2016 this directory is ''~/rada_research_project/MATLAB/RADA.''
=== Setting up the MATLAB workspace for simulation ===
Change your MATLAB directory to this directory. Then run the simulation setup files. Currently you just need to run ''modelParams_smallWheels_RADA'' in the MATLAB Command Prompt. Next open the Simulink file with that contains the model of RADA controlled by the controller you tested.
-'''RADA_psiCtrl_v2_lqi_est.slx''' contains LQI, LQI+estimation, and LQG controller simulations.
-'''RADA_psiCtrl_v2.slx''' contains the PID controlled system.
-'''RADA_psiCtrl_v2_LQGsep.slx''' contains the subsystem LQG controlled system.
-'''RADA_psiCtrl_v2_LQGsep_ol.slx''' contains the simulation of the pendulum system controlled by an LQG and Eris controlled with open-loop commands.
Note all of the current (August 2nd, 2016) ''.slx'' files were created in MATLAB 2014b and will only work in MATLAB 2014B or newer. Then in the MATLAB Command Prompt type ''X_ref.time(end)'' exactly, don't add a semicolon, and hit enter. MATLAB will print the time of the last command in the X_ref structure. Set the en time of the simulation to this value and save your Simulink file.
=== Running simulations and storing results ===
Before running the simulation make sure that the simuation is using the ''ode23t'' differential equations solver. This system is a moderately stiff system of differential and the ''ode45'' solver doesn't do well with these types of systems. When using ''ode23t'' is should only take a few minutes to run a 100+ second simulation while doing the same test using ''ode45'' could take 8 hours. While this slow it is also bad for your hard drive as the simulation has to page between RAM and your computers hard drive a lot.
Once this check is done run the simulation. While it is running check what the output structures variables are named for for your RADA test system. Once the simulation is done go to your MATLAB Workspace and select all 15 outputs for your simulation or your sub-simulation if you used '''RADA_psiCtrl_v2_lqi_est.slx'''. Save these 15 output structures to a ''.mat'' file named as the log file with _sim appended to the end of the name.
The 15 outputs are structures containing a time vector and then the data from the simulation sampled at 100 Hz and the units of this data are the SI units (ex: radians, m/s). There is one output structure for x velocity, y velocity, x body velocity, y body velocity, theta (pitch), phi (roll), psi (yaw), and one per actuator command (ex: the command sent to a wheel). Now you have all the data you can plot it.
=== Plotting results ===
If you look at the ''DataSets'' folder below ''~/rada_research_project/MATLAB/RADA'' directory there are plenty of examples of how Paul Uhing compared simulation to test data. Generally you should grate a ''.m'' file with the same name as the log file this data was extracted from with _plot appended to the name.
Generally you can just copy an for RADA_LQG_compPID_plot.m RADA_PID_compLQG_plot.m, RADA_LQG_sep_plot.m, or RADA_LQG_sep_ol_plot.m files and rename the structures for your test.
These files create four figures. Figure 1 plots compares the x velocity data in the first sub figure and compares pitch (theta) data in the second sub figure. Figure 2 does the same thing as Figure 1 but with y velocity and roll data. Figure 3 looks at the yaw data. Finally, Figure 4 looks at the sample period between UAV and ERIS packets from the camera system just to check for periods of time with large packet drops.
You can follow a similar pattern to compare motor commands. Just make sure that you compare Quad Motor 2 from the test data with Quad Motor 4 from simulation and vise versa because propellers 2 and 4 were switch in Eris's software compared to the Model.
That is all you need to know for testing RADA against the model.
5cbea2030b7bfce659c60008efa0777adae3e80d
File:QuadBattMeas.jpg
6
73
252
2016-08-02T20:42:10Z
Pfuhing
5
wikitext
text/x-wiki
da39a3ee5e6b4b0d3255bfef95601890afd80709
File:QuadMultiSet.JPG
6
74
253
2016-08-02T20:42:52Z
Pfuhing
5
wikitext
text/x-wiki
da39a3ee5e6b4b0d3255bfef95601890afd80709
File:QuadMultiCon.jpg
6
75
254
2016-08-02T20:43:28Z
Pfuhing
5
wikitext
text/x-wiki
da39a3ee5e6b4b0d3255bfef95601890afd80709
File:QuadMeasESCcon.JPG
6
76
255
2016-08-02T20:44:09Z
Pfuhing
5
wikitext
text/x-wiki
da39a3ee5e6b4b0d3255bfef95601890afd80709
File:TrackingToolsOpenTrackables.PNG
6
77
261
2016-08-03T16:12:35Z
Jnoronha
3
Crazyflie constellation trackables in camera system
wikitext
text/x-wiki
Crazyflie constellation trackables in camera system
c5c6415777f985d27fd47294431c09cfea92f639
299
261
2016-08-27T17:50:55Z
Jnoronha
3
Jnoronha uploaded a new version of [[File:TrackingToolsOpenTrackables.PNG]]
wikitext
text/x-wiki
Crazyflie constellation trackables in camera system
c5c6415777f985d27fd47294431c09cfea92f639
File:CrazyflieLocationLayoutAnnotated.png
6
78
262
2016-08-03T16:44:13Z
Jnoronha
3
Crazyflie layout in the Camera field of view
wikitext
text/x-wiki
Crazyflie layout in the Camera field of view
b1f50fd263a0e7c21941c230fd9d027f07302dd2
File:CrazyflieLocationLayoutAnnotatedSmall.png
6
79
263
2016-08-03T16:53:18Z
Jnoronha
3
Crazyflie location and orientation in the Camera system field of view
wikitext
text/x-wiki
Crazyflie location and orientation in the Camera system field of view
042911874ff40ae34740dad4b5a70f2c992253f5
298
263
2016-08-27T17:48:57Z
Jnoronha
3
Jnoronha uploaded a new version of [[File:CrazyflieLocationLayoutAnnotatedSmall.png]]
wikitext
text/x-wiki
Crazyflie location and orientation in the Camera system field of view
042911874ff40ae34740dad4b5a70f2c992253f5
PC Client Software
0
25
264
224
2016-08-03T16:57:34Z
Jnoronha
3
/* Swarm Client */ added vrpn images for running the swarm client
wikitext
text/x-wiki
The PC Client software comes in many forms. The out-of-the-box Client is written in Python and has a Graphical User Interface (GUI). The GUI is well suited for beginners, but can only support a single Radio and a single Crazyflie at a time. The easiest way to start out is with the [https://wiki.bitcraze.io/projects:virtualmachine:index Bitcraze Virtual Machine (VM)], which comes with all the files and dependencies pre-installed and can run on any computer (Windows, Mac, Linux, etc.).
For more advanced users who want to use the swarm capabilities of our platform will have to use the [[#Swarm Client|Swarm Client]] we developed in C and C++.
==[https://wiki.bitcraze.io/projects:virtualmachine:index Bitcraze VM]==
('''Note:''' The VM is updated frequently so the information below may be different than the current VM)
The Bitcraze wiki has a tutorial on [https://wiki.bitcraze.io/projects:virtualmachine:tutorials:vmware-win7 installing the VM]. Along with another tutorial on how to get started [https://www.bitcraze.io/getting-started-with-development/ using the VM].
These are both very simple starting guides that will help you become familiar with the VM.
===Crazyflie Client GUI===
On the VM you can find the Crazyflie Client Graphical User Interface (GUI). To run the Client you want to open a terminal and navigate to <code>/home/bitcraze/Desktop/projects/crazyflie-clients-python/</code> and then run the command <code>sudo ./bin/cfclient</code>
(Alternatively, you can use the desktop to navigate to the folder and open a terminal there)
Once you do that you should see something similar to this:
[[Image:DefaultCrazyflieGUIMainScreen.JPG|500px]]
This is the main screen of the Client GUI and there are many tabs and features that you can access directly from this screen.
The most important parts of this screen are the following:
#Connect Button
#Bootloader (Crazyflie Drop Down -> Bootloader)
#Plotter Tab
#Log Blocks Tab
#Parameters Tab
====Connect Button====
This is where you will scan for Crazyflies that are powered ON. All Crazyflies not already connected will show up in the popup
[[Image:DefaultCrazyflieGUIConnectScreen.JPG|400px]]
We get a return that says <code>radio://0/45/2M</code>, this line is the identifier string of the Crazyflie we are trying to connect to.
What this is saying is that we got a return from:
#Radio 0 (the first radio)
#Crazyflie on Channel 45
#Using a data rate of 2Mbps
====Bootloader====
This where you can install new Firmware to the Crazyflie.
[[Image:DefaultCrazyflieGUIBootloader.JPG|500px]]
The first thing you'll need to update is to build the Firmware version you want into a .bin file. You can do this by just running the <code>make</code> command in terminal while located inside the Firmware directory you have modified.
Once you have that .bin file built you:
#Open the bootloader shown
#Hold down the power button on the Crazyflie 2.0 for around 3 seconds until the 2 blue LED's flash and alternate. This puts the Crazyflie in bootloader mode. ('''NOTE:''' Recommend having '''ALL other Crazyflies OFF''' or else it could accidentally flash both Crazyflies.)
#Then hit ''Initiate bootloader cold boot'' (it should connect to the Crazyflie in bootloader mode after a few seconds, Status will change from 'Not Connected' to 'Connected')
#Hit ''Browse'' and find the .bin file you built earlier.
#Then click ''Program'' and wait for the progress bar to complete.
#Restart the Crazyflie in Firmware mode and make sure it starts up normally, if something seems wrong just repeat steps 2 through 6 again.
====Logging Tab====
Once you connect to a Crazyflie you can monitor certain log variables that have been set up. You will see a plot of the data similar to this:
[[Image:DefaultCrazyflieGUILoggerScreen.JPG|400px]]
On this screen we can do the following things:
*Dropdown Menu at the top of the screen
**Select which log block you want to plot on screen.
*Scale the X-axis of the plot by:
**Range
**Number of Samples
**Time in Seconds
**Manually
*Scale the Y-axis by:
**Automatically
**Manual Range
====Parameters Tab====
This tab displays all the parameters currently set up on the Crazyflie Firmware. Once you connect to a Crazyflie it lists these parameters in a table format similar to below:
[[Image:DefaultCrazyflieGUIParametersScreen.JPG|400px]]
For each parameter we get its Name, Variable Type, Access Type (Read/Write), and its Current Value.
We can also modify the parameter values on this screen in real-time and the changes will be sent to the Crazyflie automatically.
('''Note:''' Any parameter changes made on this screen are NOT preserved when you turn OFF the Crazyflie.)
==Swarm Client==
The swarm Client is a re-creation of the Original Client but programmed in C and C++.
The benefit of this is that
*We use a unified language between Client and Firmware
*Easily migrate this platform to any linux distribution that can install the Crazyflie dependencies.
**Our platform code itself requires only the VRPN libraries and a generic C compiler.
===Using the Swarm Client===
The Swarm Client uses the terminal interface for User Input.
[[Image:CrazyflieTerminalInitial.png|400px]]
Here we see what the initial Terminal looks like before we do anything.
:1. The first thing you want to do before any testing is to run the <code>sudo make</code> command in the Swarm Client directory. (Yes, the 'sudo' is necessary)
::This will make sure you have all the necessary dependencies, that the code is error free, and then it will build an executable (.exe) file of the Swarm Client code. An error free make will look something like this:
::[[Image:CrazyflieTerminalPostMake.png|400px]]
::There will be warnings, but those don't cause any issues right now.
:2. Pre-Test Checklist
::*Camera System is Turned on and Crazyflie Trackables are opened and visible.
:::[[Image:TrackingToolsOpenTrackables.PNG|400px]] [[Image:TrackingToolsCrazyflieConstellationZeroing.png|400px]]
::*Radios are plugged into the USB Ports on the Client computer.
::*Crazyflies are ON and NOT in an Error State.
::**'''IMPORTANT!!!''' Face Crazyflie 'Nose' (Red Dot in picture) towards the East wall when powering ON! (to synch yaw correctly)
:::[[Image:CrazyflieLocationLayoutAnnotatedSmall.png|500px]]
:3. Run the executable file using the command <code>sudo ./eris_vrpn</code> in the same directory (Yes, the 'sudo' is necessary). This will start the program initialization and a bunch of status info will flood the screen. You will know the program is ready for input when you see the following:
::[[Image:CrazyflieTerminalProgramStarted.png|400px]]
::This means that the Crazyflie yaw has been synchronized with the Camera system and they are ready to fly.
:4. Input a Keyboard Command
::This will depend on what you have programmed as the keyboard input commands. As of 7/19/16 we have the following Keyboard Commands active:
::*'1' - Rotates Yaw of Crazyflie1 +45 degrees
::*'2' - Rotates Yaw of Crazyflie1 -45 degrees
::*'q' - Ends Main Loop (OBSOLETE - Replaced with ctrl + c)
::*'e' - Landing Mode (for ALL Crazyflies)
::*'t' - Crazyflie1 Take-Off
::*'y' - Crazyflie2 Take-Off
::*'u' - Crazyflie3 Take-Off
::*'i' - Crazyflie4 Take-Off
::*'h' - Hand Gesture Mode (for ALL Crazyflies)
::*'m' - Mirror Mode (for ALL Crazyflies)
::*ctrl+c - Quits Program, performs all cleanup.
::An example of what this would look like in the Terminal is shown here:
::[[Image:CrazyflieTerminalKeyboardInput.png|400px]]
::So you can see we commanded all 4 Crazyflies to take off (t,y,u,i), then activated Landing Mode (e), then activated Hand Mode (h), and then Ended the Program (ctrl+c).
:5. End Program when finished (ctrl+c)
::This will end the program loop, print the current battery levels, and Delete the Radio pointers (shown at the end of the previous figure)
===Makefile===
The Swarm Client is compiled by a simple makefile. So when you call ''sudo make'' this makefile converts the C++ code files into an executable (.exe) for us.
<blockquote>
<code>
<pre>
g++ = g++ -Wall
all: eris_vrpn
eris_vrpn: eris_vrpn.h eris_vrpn.cpp vrpn.h vrpn.cpp CCrazyflie.h CCrazyflie.cpp
CCrazyRadio.h CCrazyRadio.cpp CCRTPPacket.h CCRTPPacket.cpp CTOC.h CTOC.cpp
simple.cpp simple.h pid.h pid.c controller.h controller.c multicast.c
$(g++) -g -O0 -o eris_vrpn eris_vrpn.cpp vrpn.cpp CCrazyflie.cpp
CCrazyRadio.cpp CCRTPPacket.cpp CTOC.cpp simple.cpp pid.c controller.c
multicast.c -lquat -lvrpn -lpthread -lusb-1.0
clean:
rm -f *.o eris_vrpn
</pre>
</code>
</blockquote>
----
<center> '''Main Directory''' </center>
<center> [[Crazyflie Swarm|Crazyflie Swarm Home]] | [[PC Client Software]] | [[USB Radio]] | [[Firmware]] | [[FAQ]] </center>
<center> '''Modifications Directory''' </center>
<center> [[Controller]] | [[Logging]] | [[Keyboard Commands]] | [[USB Radio#Changing Radio Channel|Changing Radio Channel]] | [[Flight Modes]] | [[Callbacks]] | [[Adding a Crazyflie]] | [[Firmware]] </center>
18fc8b4ae2b769b12c7090e3c905f41984429db5
265
264
2016-08-03T16:58:29Z
Jnoronha
3
added spacing between major sections
wikitext
text/x-wiki
The PC Client software comes in many forms. The out-of-the-box Client is written in Python and has a Graphical User Interface (GUI). The GUI is well suited for beginners, but can only support a single Radio and a single Crazyflie at a time. The easiest way to start out is with the [https://wiki.bitcraze.io/projects:virtualmachine:index Bitcraze Virtual Machine (VM)], which comes with all the files and dependencies pre-installed and can run on any computer (Windows, Mac, Linux, etc.).
For more advanced users who want to use the swarm capabilities of our platform will have to use the [[#Swarm Client|Swarm Client]] we developed in C and C++.
==[https://wiki.bitcraze.io/projects:virtualmachine:index Bitcraze VM]==
('''Note:''' The VM is updated frequently so the information below may be different than the current VM)
The Bitcraze wiki has a tutorial on [https://wiki.bitcraze.io/projects:virtualmachine:tutorials:vmware-win7 installing the VM]. Along with another tutorial on how to get started [https://www.bitcraze.io/getting-started-with-development/ using the VM].
These are both very simple starting guides that will help you become familiar with the VM.
===Crazyflie Client GUI===
On the VM you can find the Crazyflie Client Graphical User Interface (GUI). To run the Client you want to open a terminal and navigate to <code>/home/bitcraze/Desktop/projects/crazyflie-clients-python/</code> and then run the command <code>sudo ./bin/cfclient</code>
(Alternatively, you can use the desktop to navigate to the folder and open a terminal there)
Once you do that you should see something similar to this:
[[Image:DefaultCrazyflieGUIMainScreen.JPG|500px]]
This is the main screen of the Client GUI and there are many tabs and features that you can access directly from this screen.
The most important parts of this screen are the following:
#Connect Button
#Bootloader (Crazyflie Drop Down -> Bootloader)
#Plotter Tab
#Log Blocks Tab
#Parameters Tab
====Connect Button====
This is where you will scan for Crazyflies that are powered ON. All Crazyflies not already connected will show up in the popup
[[Image:DefaultCrazyflieGUIConnectScreen.JPG|400px]]
We get a return that says <code>radio://0/45/2M</code>, this line is the identifier string of the Crazyflie we are trying to connect to.
What this is saying is that we got a return from:
#Radio 0 (the first radio)
#Crazyflie on Channel 45
#Using a data rate of 2Mbps
====Bootloader====
This where you can install new Firmware to the Crazyflie.
[[Image:DefaultCrazyflieGUIBootloader.JPG|500px]]
The first thing you'll need to update is to build the Firmware version you want into a .bin file. You can do this by just running the <code>make</code> command in terminal while located inside the Firmware directory you have modified.
Once you have that .bin file built you:
#Open the bootloader shown
#Hold down the power button on the Crazyflie 2.0 for around 3 seconds until the 2 blue LED's flash and alternate. This puts the Crazyflie in bootloader mode. ('''NOTE:''' Recommend having '''ALL other Crazyflies OFF''' or else it could accidentally flash both Crazyflies.)
#Then hit ''Initiate bootloader cold boot'' (it should connect to the Crazyflie in bootloader mode after a few seconds, Status will change from 'Not Connected' to 'Connected')
#Hit ''Browse'' and find the .bin file you built earlier.
#Then click ''Program'' and wait for the progress bar to complete.
#Restart the Crazyflie in Firmware mode and make sure it starts up normally, if something seems wrong just repeat steps 2 through 6 again.
====Logging Tab====
Once you connect to a Crazyflie you can monitor certain log variables that have been set up. You will see a plot of the data similar to this:
[[Image:DefaultCrazyflieGUILoggerScreen.JPG|400px]]
On this screen we can do the following things:
*Dropdown Menu at the top of the screen
**Select which log block you want to plot on screen.
*Scale the X-axis of the plot by:
**Range
**Number of Samples
**Time in Seconds
**Manually
*Scale the Y-axis by:
**Automatically
**Manual Range
====Parameters Tab====
This tab displays all the parameters currently set up on the Crazyflie Firmware. Once you connect to a Crazyflie it lists these parameters in a table format similar to below:
[[Image:DefaultCrazyflieGUIParametersScreen.JPG|400px]]
For each parameter we get its Name, Variable Type, Access Type (Read/Write), and its Current Value.
We can also modify the parameter values on this screen in real-time and the changes will be sent to the Crazyflie automatically.
('''Note:''' Any parameter changes made on this screen are NOT preserved when you turn OFF the Crazyflie.)
==Swarm Client==
The swarm Client is a re-creation of the Original Client but programmed in C and C++.
The benefit of this is that
*We use a unified language between Client and Firmware
*Easily migrate this platform to any linux distribution that can install the Crazyflie dependencies.
**Our platform code itself requires only the VRPN libraries and a generic C compiler.
===Using the Swarm Client===
The Swarm Client uses the terminal interface for User Input.
[[Image:CrazyflieTerminalInitial.png|400px]]
Here we see what the initial Terminal looks like before we do anything.
:1. The first thing you want to do before any testing is to run the <code>sudo make</code> command in the Swarm Client directory. (Yes, the 'sudo' is necessary)
::This will make sure you have all the necessary dependencies, that the code is error free, and then it will build an executable (.exe) file of the Swarm Client code. An error free make will look something like this:
::[[Image:CrazyflieTerminalPostMake.png|400px]]
::There will be warnings, but those don't cause any issues right now.
:2. Pre-Test Checklist
::*Camera System is Turned on and Crazyflie Trackables are opened and visible.
:::[[Image:TrackingToolsOpenTrackables.PNG|400px]] [[Image:TrackingToolsCrazyflieConstellationZeroing.png|400px]]
::*Radios are plugged into the USB Ports on the Client computer.
::*Crazyflies are ON and NOT in an Error State.
::**'''IMPORTANT!!!''' Face Crazyflie 'Nose' (Red Dot in picture) towards the East wall when powering ON! (to synch yaw correctly)
:::[[Image:CrazyflieLocationLayoutAnnotatedSmall.png|500px]]
:3. Run the executable file using the command <code>sudo ./eris_vrpn</code> in the same directory (Yes, the 'sudo' is necessary). This will start the program initialization and a bunch of status info will flood the screen. You will know the program is ready for input when you see the following:
::[[Image:CrazyflieTerminalProgramStarted.png|400px]]
::This means that the Crazyflie yaw has been synchronized with the Camera system and they are ready to fly.
:4. Input a Keyboard Command
::This will depend on what you have programmed as the keyboard input commands. As of 7/19/16 we have the following Keyboard Commands active:
::*'1' - Rotates Yaw of Crazyflie1 +45 degrees
::*'2' - Rotates Yaw of Crazyflie1 -45 degrees
::*'q' - Ends Main Loop (OBSOLETE - Replaced with ctrl + c)
::*'e' - Landing Mode (for ALL Crazyflies)
::*'t' - Crazyflie1 Take-Off
::*'y' - Crazyflie2 Take-Off
::*'u' - Crazyflie3 Take-Off
::*'i' - Crazyflie4 Take-Off
::*'h' - Hand Gesture Mode (for ALL Crazyflies)
::*'m' - Mirror Mode (for ALL Crazyflies)
::*ctrl+c - Quits Program, performs all cleanup.
::An example of what this would look like in the Terminal is shown here:
::[[Image:CrazyflieTerminalKeyboardInput.png|400px]]
::So you can see we commanded all 4 Crazyflies to take off (t,y,u,i), then activated Landing Mode (e), then activated Hand Mode (h), and then Ended the Program (ctrl+c).
:5. End Program when finished (ctrl+c)
::This will end the program loop, print the current battery levels, and Delete the Radio pointers (shown at the end of the previous figure)
===Makefile===
The Swarm Client is compiled by a simple makefile. So when you call ''sudo make'' this makefile converts the C++ code files into an executable (.exe) for us.
<blockquote>
<code>
<pre>
g++ = g++ -Wall
all: eris_vrpn
eris_vrpn: eris_vrpn.h eris_vrpn.cpp vrpn.h vrpn.cpp CCrazyflie.h CCrazyflie.cpp
CCrazyRadio.h CCrazyRadio.cpp CCRTPPacket.h CCRTPPacket.cpp CTOC.h CTOC.cpp
simple.cpp simple.h pid.h pid.c controller.h controller.c multicast.c
$(g++) -g -O0 -o eris_vrpn eris_vrpn.cpp vrpn.cpp CCrazyflie.cpp
CCrazyRadio.cpp CCRTPPacket.cpp CTOC.cpp simple.cpp pid.c controller.c
multicast.c -lquat -lvrpn -lpthread -lusb-1.0
clean:
rm -f *.o eris_vrpn
</pre>
</code>
</blockquote>
----
<center> '''Main Directory''' </center>
<center> [[Crazyflie Swarm|Crazyflie Swarm Home]] | [[PC Client Software]] | [[USB Radio]] | [[Firmware]] | [[FAQ]] </center>
<center> '''Modifications Directory''' </center>
<center> [[Controller]] | [[Logging]] | [[Keyboard Commands]] | [[USB Radio#Changing Radio Channel|Changing Radio Channel]] | [[Flight Modes]] | [[Callbacks]] | [[Adding a Crazyflie]] | [[Firmware]] </center>
2aafe7e6665dc99268922ebede8235d6d081581e
FAQ
0
40
266
244
2016-08-03T17:03:40Z
Jnoronha
3
added question 6
wikitext
text/x-wiki
Here you can find some Frequently Asked Questions:
:'''1. How do I change the Radio Channel?'''
::Find out here: [[:USB Radio#Changing Radio Channel|Changing the Radio Channel]]
:'''2. How do I use Log Blocks?'''
::*Creating and using [[:Logging#Client-Side External Log Files|External Client-side Log Files]]
::*Creating [[:Firmware#New Firmware Log Blocks|New Log Blocks in Firmware]]
::*Creating and Using [[:Logging#New Client Log Blocks|New Log Blocks in Client]]
:'''3. I just want to run the code, how do I run it?'''
::See [[:PC Client Software#Using the Swarm Client|Using the Swarm Client]]
:'''4. What are the Keyboard Commands for flying the Crazyflie?'''
::You can find a full list of all the Key Commands in [[:Keyboard Commands]]
::(Alternatively: See '''Step 4''' of [[:PC Client Software#Using the Swarm Client|Using the Swarm Client]])
:'''5. How do I plot the Log Files that the Crazyflie Swarm Creates?'''
::See the [[:Logging#MATLAB Parser|MATLAB Parser]] section for examples.
:'''6. Can I change what files are compiled during <code>make</code>?'''
::Yep! You need to modify the makefile in the Client directory. Follow the example shown [[:PC Client Software#Makefile|here]].
----
<center> '''Main Directory''' </center>
<center> [[Crazyflie Swarm|Crazyflie Swarm Home]] | [[PC Client Software]] | [[USB Radio]] | [[Firmware]] | [[FAQ]] </center>
<center> '''Modifications Directory''' </center>
<center> [[Controller]] | [[Logging]] | [[Keyboard Commands]] | [[USB Radio#Changing Radio Channel|Changing Radio Channel]] | [[Flight Modes]] | [[Callbacks]] | [[Adding a Crazyflie]] | [[Firmware]] </center>
3fc08456cdd2222fd5a08d6e06b57f8f711421e5
267
266
2016-08-03T17:06:19Z
Jnoronha
3
bolded links
wikitext
text/x-wiki
Here you can find some Frequently Asked Questions:
:'''1. How do I change the Radio Channel?'''
::Find out here: '''[[:USB Radio#Changing Radio Channel|Changing the Radio Channel]]'''
:'''2. How do I use Log Blocks?'''
::*Creating and using '''[[:Logging#Client-Side External Log Files|External Client-side Log Files]]'''
::*Creating '''[[:Firmware#New Firmware Log Blocks|New Log Blocks in Firmware]]'''
::*Creating and Using '''[[:Logging#New Client Log Blocks|New Log Blocks in Client]]'''
:'''3. I just want to run the code, how do I run it?'''
::See '''[[:PC Client Software#Using the Swarm Client|Using the Swarm Client]]'''
:'''4. What are the Keyboard Commands for flying the Crazyflie?'''
::You can find a full list of all the Key Commands in '''[[:Keyboard Commands]]'''
::(Alternatively: See '''Step 4''' of '''[[:PC Client Software#Using the Swarm Client|Using the Swarm Client]]''')
:'''5. How do I plot the Log Files that the Crazyflie Swarm Creates?'''
::See the '''[[:Logging#MATLAB Parser|MATLAB Parser]]''' section for examples.
:'''6. Can I change what files are compiled during <code>make</code>?'''
::Yep! You need to modify the makefile in the Client directory. You can follow the example shown '''[[:PC Client Software#Makefile|here]]''' or make your own if you know how (but then this question would be irrelevant to you...).
----
<center> '''Main Directory''' </center>
<center> [[Crazyflie Swarm|Crazyflie Swarm Home]] | [[PC Client Software]] | [[USB Radio]] | [[Firmware]] | [[FAQ]] </center>
<center> '''Modifications Directory''' </center>
<center> [[Controller]] | [[Logging]] | [[Keyboard Commands]] | [[USB Radio#Changing Radio Channel|Changing Radio Channel]] | [[Flight Modes]] | [[Callbacks]] | [[Adding a Crazyflie]] | [[Firmware]] </center>
0a131580999a0d24fba0c422b4c9b66020eec7e7
Crazyflie Swarm
0
2
268
245
2016-08-03T17:56:58Z
Jnoronha
3
/* Future Project Ideas */ bolded future project ideas
wikitext
text/x-wiki
The Crazyflie Swarm is a Networked Control platform designed for students to learn more about control and for researchers that wish to apply their research in practice. Platform development was started during the Summer of 2015 and continues to this day.
Here you will find descriptions on how the platform works, how you can use it, and how you can get involved in developing the platform further!
== Frequently Asked Questions ==
For help with common problems and troubleshooting please see the [[FAQ]].
== Background ==
The Crazyflie Swarm platform is based off of the ''Crazyflie'' Nano-quadcopter produced and maintained by [https://www.bitcraze.io/ Bitcraze]. The ''Crazyflie'' is completely open-source so we are able to look at and modify any part of the code and customize it to our needs.
=== Major Platform Components: ===
[[Image: High_Level_Figure_(Single_Radio_Single_Crazyflie_NO_NUMBERS_CROPPED).jpg|thumb|right|A high level overview of the Crazyflie Platform]]
*[[PC Client Software]]
*[[Firmware]]
*[[USB Radio]]
== Modifying the Platform ==
[[Image:SingleRadioMultiCrazyflie.jpg|thumb|right|A high level overview of the Swarm Platform we created]]
*[[Controller]]
*[[Logging]]
*[[Keyboard Commands]]
*[[USB Radio#Changing Radio Channel|Changing Radio Channel]]
*[[Flight Modes]]
*[[Callbacks]]
*[[Adding a Crazyflie]]
*[[:Firmware]]
==Future Project Ideas==
The whole concept of this Platform is to constantly expand its capabilities. If you are interested in developing this platform further here are some ideas to get you started! Additional details on any of these ideas can be found on the '''[[Future Project Ideas]]''' page.
*[[:Future Project Ideas#Migrating Swarm Client PID's to Firmware|Migrating Swarm Client PID's to Firmware]]
*[[:Future Project Ideas#Model Development/Verification and Tuning X, Y, and Z Location PID's|Model Development/Verification and Tuning X, Y, and Z Location PID's]]
*[[:Future Project Ideas#Adding Parameter Support to Swarm Client|Adding Parameter Support to Swarm Client]]
*[[:Future Project Ideas#Threading Each USB Radio to speed up Computation|Threading Each USB Radio to speed up Computation]]
*[[:Future Project Ideas#Developing New Controllers for the Crazyflie (pending Model Development)|Developing New Controllers for the Crazyflie (pending Model Development)]]
*[[:Future Project Ideas#Develop Communications Network Between Crazyflies|Develop Communications Network Between Crazyflies]]
*[[:Future Project Ideas#Trilateration Position Estimation using a Swarm|Trilateration Position Estimation using a Swarm]]
== [https://wiki.bitcraze.io/ Bitcraze Wiki] ==
Bitcraze maintains their own wiki on the many Crazyflie systems. If you can't find what you are looking for here, chances are they will have something to help.
c59c02b73a7a5e9fd8ba633f60e99387f3f9a291
Future Project Ideas
0
47
269
176
2016-08-03T18:18:21Z
Jnoronha
3
/* Developing New Controllers for the Crazyflie (pending Model Development) */ finished
wikitext
text/x-wiki
Here we will go into more depth on what each of these projects would require:
==Migrating Swarm Client PID's to Firmware==
===Focus Area===
'''Firmware Programming and Communication Protocols'''
*This project requires heavy modification of the Firmware and Communication systems inside the Crazyflie.
===Tasks===
====Firmware====
*'''(HARD)''' Modifying [https://wiki.bitcraze.io/projects:crazyflie:crtp:commander Commander Packet Structure] to allow position data to be sent rather than pitch, roll, yaw, and thrust setpoints.
*Modifying Firmware to pass the new position data into the correct place for use by the Firmware PID controllers.
====Client====
*Modify Swarm Client packet construction to match new commander packet protocol in Firmware
*'''(EASY)''' Remove Controllers from callbacks and just send location packets to Crazyflies while still maintaining other functionality.
===Benefits===
*Significantly reduces Client-side computation and allows Crazyflie swarm to share the load.
*'''Potential extension:''' Completely independent Crazyflie flight (i.e. No Client needed at all)
==Model Development/Verification and Tuning X, Y, and Z Location PID's==
===Focus Area===
'''Control Systems and Model Development/Verification'''
*This project will require developing a model of the Crazyflie system and using the Model to calculate PID constants.
===Tasks===
*'''(HARD)''' Identify model Parameters for the Crazyflie
*Construct model in Simulink and Verify simulation compared to test data
*'''(EASY)''' Derive PID constants from verified model, test flight performance
===Benefits===
*'''VERIFIED MODEL!!''' We can do many things once we have a verified model of the system.
*Flight performance will be greatly improved allowing more complex applications to be developed.
*'''Potential extension:''' Path prediction algorithms and optimal pathing between points with obstacles
==Adding Parameter Support to Swarm Client==
===Focus Area===
'''Communications Protocols and Networking'''
*This project will require Client-side software development to create helper functions for easy modification of parameters on the Crazyflie Firmware
===Tasks===
*Creating packet framework in the Client to replicate the [https://wiki.bitcraze.io/projects:crazyflie:firmware:comm_protocol#parameters parameters packet protocol]
*Programming helper functions to make it simple to modify parameters
**Ex. Write Parameter Value: <code>setParam(string "param_group.param_name", int set_value);</code>
**Ex. Read Parameter Value: <code>readParam(string "param_group.param_name");</code>
===Benefits===
*Won't have to re-flash Firmware every time we want to test a parameter change (Improves Firmware testing efficiency)
*Less Firmware modification if we can just write params during Client init.
*'''Potential Extension:''' Tuning Firmware PID constants
==Threading Each USB Radio to speed up Computation==
===Focus Area===
'''Computer Architecture and Parallelization'''
*This project will require/develop a good understanding of parallel processing and computer architecture.
===Tasks===
*Apply threading to each USB Radio individually
**A single Radio will be assigned at most 3 Crazyflies, and each thread will handle the corresponding Callbacks for those Crazyflies (which includes control calculations, Radio communications, and logging for each Crazyflie)
*Troubleshoot any issues that come up with non-sequential program execution (shouldn't have problems)
===Benefits===
*Greatly reduces time required to complete a loop cycle (relative to number of Crazyflies in the Swarm)
**Improves scalability of the Swarm since we don't need to worry about missing the Camera System new data timing deadline as the Swarm size increases
*'''Potential Extension:''' Increasing Swarm size to Camera System capacity limit.
==Developing New Controllers for the Crazyflie (pending Model Development)==
===Focus Area===
'''Control System Development and Implementation'''
*This project will require a background in theoretical controls modeling and systems design.
===Tasks===
*Research Control Designs and decide which controller you want to use
**Examples: State Feedback Control (LQR, LQI, Pole Placement), State Space Controller (Lyapunov Estimator, H2), etc..
*Develop a Simulink model for the controller and implement design in C++.
*Verify model by comparing to real-world tests on the Crazyflie Swarm!
===Benefits===
*Improved flight control leading to more complex applications
*Maintain control without all the information (State Estimation)
*'''Potential Extension:''' Stable control with Stochastic lossy packet transmission
==Develop Communications Network Between Crazyflies==
==Trilateration Position Estimation using a Swarm==
----
<center> '''Main Directory''' </center>
<center> [[Crazyflie Swarm|Crazyflie Swarm Home]] | [[PC Client Software]] | [[USB Radio]] | [[Firmware]] | [[FAQ]] </center>
<center> '''Modifications Directory''' </center>
<center> [[Controller]] | [[Logging]] | [[Keyboard Commands]] | [[USB Radio#Changing Radio Channel|Changing Radio Channel]] | [[Flight Modes]] | [[Callbacks]] | [[Adding a Crazyflie]] | [[Firmware]] </center>
35354c16a4b6ae4e3b2e27c39653ccfa10d1c715
272
269
2016-08-03T19:02:38Z
Jnoronha
3
/* Develop Communications Network Between Crazyflies */ Finished section
wikitext
text/x-wiki
Here we will go into more depth on what each of these projects would require:
==Migrating Swarm Client PID's to Firmware==
===Focus Area===
'''Firmware Programming and Communication Protocols'''
*This project requires heavy modification of the Firmware and Communication systems inside the Crazyflie.
===Tasks===
====Firmware====
*'''(HARD)''' Modifying [https://wiki.bitcraze.io/projects:crazyflie:crtp:commander Commander Packet Structure] to allow position data to be sent rather than pitch, roll, yaw, and thrust setpoints.
*Modifying Firmware to pass the new position data into the correct place for use by the Firmware PID controllers.
====Client====
*Modify Swarm Client packet construction to match new commander packet protocol in Firmware
*'''(EASY)''' Remove Controllers from callbacks and just send location packets to Crazyflies while still maintaining other functionality.
===Benefits===
*Significantly reduces Client-side computation and allows Crazyflie swarm to share the load.
*'''Potential extension:''' Completely independent Crazyflie flight (i.e. No Client needed at all)
==Model Development/Verification and Tuning X, Y, and Z Location PID's==
===Focus Area===
'''Control Systems and Model Development/Verification'''
*This project will require developing a model of the Crazyflie system and using the Model to calculate PID constants.
===Tasks===
*'''(HARD)''' Identify model Parameters for the Crazyflie
*Construct model in Simulink and Verify simulation compared to test data
*'''(EASY)''' Derive PID constants from verified model, test flight performance
===Benefits===
*'''VERIFIED MODEL!!''' We can do many things once we have a verified model of the system.
*Flight performance will be greatly improved allowing more complex applications to be developed.
*'''Potential extension:''' Path prediction algorithms and optimal pathing between points with obstacles
==Adding Parameter Support to Swarm Client==
===Focus Area===
'''Communications Protocols and Networking'''
*This project will require Client-side software development to create helper functions for easy modification of parameters on the Crazyflie Firmware
===Tasks===
*Creating packet framework in the Client to replicate the [https://wiki.bitcraze.io/projects:crazyflie:firmware:comm_protocol#parameters parameters packet protocol]
*Programming helper functions to make it simple to modify parameters
**Ex. Write Parameter Value: <code>setParam(string "param_group.param_name", int set_value);</code>
**Ex. Read Parameter Value: <code>readParam(string "param_group.param_name");</code>
===Benefits===
*Won't have to re-flash Firmware every time we want to test a parameter change (Improves Firmware testing efficiency)
*Less Firmware modification if we can just write params during Client init.
*'''Potential Extension:''' Tuning Firmware PID constants
==Threading Each USB Radio to speed up Computation==
===Focus Area===
'''Computer Architecture and Parallelization'''
*This project will require/develop a good understanding of parallel processing and computer architecture.
===Tasks===
*Apply threading to each USB Radio individually
**A single Radio will be assigned at most 3 Crazyflies, and each thread will handle the corresponding Callbacks for those Crazyflies (which includes control calculations, Radio communications, and logging for each Crazyflie)
*Troubleshoot any issues that come up with non-sequential program execution (shouldn't have problems)
===Benefits===
*Greatly reduces time required to complete a loop cycle (relative to number of Crazyflies in the Swarm)
**Improves scalability of the Swarm since we don't need to worry about missing the Camera System new data timing deadline as the Swarm size increases
*'''Potential Extension:''' Increasing Swarm size to Camera System capacity limit.
==Developing New Controllers for the Crazyflie (pending Model Development)==
===Focus Area===
'''Control System Development and Implementation'''
*This project will require a background in theoretical controls modeling and systems design.
===Tasks===
*Research Control Designs and decide which controller you want to use
**Examples: State Feedback Control (LQR, LQI, Pole Placement), State Space Controller (Lyapunov Estimator, H2), etc..
*Develop a Simulink model for the controller and implement design in C++.
*Verify model by comparing to real-world tests on the Crazyflie Swarm!
===Benefits===
*Improved flight control leading to more complex applications
*Maintain control without all the information (State Estimation)
*'''Potential Extension:''' Stable control with Stochastic lossy packet transmission
==Develop Communications Network Between Crazyflies==
===Focus Area===
'''Communication Networking and Firmware Development'''
*This project will require/develop a good understanding of network protocols and creating complex communications networks
===Tasks===
*Research the Crazy RealTime Protocol (CRTP) used by the Crazyflie
**[https://wiki.bitcraze.io/projects:crazyflie:firmware:comm_protocol CRTP Protocol]
**[https://github.com/bitcraze/crazyflie2-nrf-firmware/blob/master/src/esb.c Enhanced Shock Burst USB Radio Protocol]
*'''(HARD)''' Modify the Crazyflie Firmware to enable both transmit (tx) and receive (rx) packets
*'''(HARD)''' Develop a system in Firmware to utilize the bi-directional communications
**Example: Using the pitch, roll, or yaw of a Crazyflie to influence control of another Crazyflie(s) without passing it through the Swarm Client
===Benefits===
*Crazyflies can pass information between themselves
*Stepping stone to fully autonomous Crazyflie Swamrs (No Client needed)
*Opens up many possible extended applications
*'''Potential Extensions:'''
**Relative Swarm Formations (patterns based on distance from other members of the swarm, not some global entity)
**Create Advanced [[#Trilateration Position Estimation using a Swarm|Trilateration Localization]] using Swarm itself
==Trilateration Position Estimation using a Swarm==
----
<center> '''Main Directory''' </center>
<center> [[Crazyflie Swarm|Crazyflie Swarm Home]] | [[PC Client Software]] | [[USB Radio]] | [[Firmware]] | [[FAQ]] </center>
<center> '''Modifications Directory''' </center>
<center> [[Controller]] | [[Logging]] | [[Keyboard Commands]] | [[USB Radio#Changing Radio Channel|Changing Radio Channel]] | [[Flight Modes]] | [[Callbacks]] | [[Adding a Crazyflie]] | [[Firmware]] </center>
763afd32a286ce2dd344f4af35499fe26f7bd274
273
272
2016-08-03T19:31:52Z
Jnoronha
3
/* Trilateration Position Estimation using a Swarm */ finished
wikitext
text/x-wiki
Here we will go into more depth on what each of these projects would require:
==Migrating Swarm Client PID's to Firmware==
===Focus Area===
'''Firmware Programming and Communication Protocols'''
*This project requires heavy modification of the Firmware and Communication systems inside the Crazyflie.
===Tasks===
====Firmware====
*'''(HARD)''' Modifying [https://wiki.bitcraze.io/projects:crazyflie:crtp:commander Commander Packet Structure] to allow position data to be sent rather than pitch, roll, yaw, and thrust setpoints.
*Modifying Firmware to pass the new position data into the correct place for use by the Firmware PID controllers.
====Client====
*Modify Swarm Client packet construction to match new commander packet protocol in Firmware
*'''(EASY)''' Remove Controllers from callbacks and just send location packets to Crazyflies while still maintaining other functionality.
===Benefits===
*Significantly reduces Client-side computation and allows Crazyflie swarm to share the load.
*'''Potential extension:''' Completely independent Crazyflie flight (i.e. No Client needed at all)
==Model Development/Verification and Tuning X, Y, and Z Location PID's==
===Focus Area===
'''Control Systems and Model Development/Verification'''
*This project will require developing a model of the Crazyflie system and using the Model to calculate PID constants.
===Tasks===
*'''(HARD)''' Identify model Parameters for the Crazyflie
*Construct model in Simulink and Verify simulation compared to test data
*'''(EASY)''' Derive PID constants from verified model, test flight performance
===Benefits===
*'''VERIFIED MODEL!!''' We can do many things once we have a verified model of the system.
*Flight performance will be greatly improved allowing more complex applications to be developed.
*'''Potential extension:''' Path prediction algorithms and optimal pathing between points with obstacles
==Adding Parameter Support to Swarm Client==
===Focus Area===
'''Communications Protocols and Networking'''
*This project will require Client-side software development to create helper functions for easy modification of parameters on the Crazyflie Firmware
===Tasks===
*Creating packet framework in the Client to replicate the [https://wiki.bitcraze.io/projects:crazyflie:firmware:comm_protocol#parameters parameters packet protocol]
*Programming helper functions to make it simple to modify parameters
**Ex. Write Parameter Value: <code>setParam(string "param_group.param_name", int set_value);</code>
**Ex. Read Parameter Value: <code>readParam(string "param_group.param_name");</code>
===Benefits===
*Won't have to re-flash Firmware every time we want to test a parameter change (Improves Firmware testing efficiency)
*Less Firmware modification if we can just write params during Client init.
*'''Potential Extension:''' Tuning Firmware PID constants
==Threading Each USB Radio to speed up Computation==
===Focus Area===
'''Computer Architecture and Parallelization'''
*This project will require/develop a good understanding of parallel processing and computer architecture.
===Tasks===
*Apply threading to each USB Radio individually
**A single Radio will be assigned at most 3 Crazyflies, and each thread will handle the corresponding Callbacks for those Crazyflies (which includes control calculations, Radio communications, and logging for each Crazyflie)
*Troubleshoot any issues that come up with non-sequential program execution (shouldn't have problems)
===Benefits===
*Greatly reduces time required to complete a loop cycle (relative to number of Crazyflies in the Swarm)
**Improves scalability of the Swarm since we don't need to worry about missing the Camera System new data timing deadline as the Swarm size increases
*'''Potential Extension:''' Increasing Swarm size to Camera System capacity limit.
==Developing New Controllers for the Crazyflie (pending Model Development)==
===Focus Area===
'''Control System Development and Implementation'''
*This project will require a background in theoretical controls modeling and systems design.
===Tasks===
*Research Control Designs and decide which controller you want to use
**Examples: State Feedback Control (LQR, LQI, Pole Placement), State Space Controller (Lyapunov Estimator, H2), etc..
*Develop a Simulink model for the controller and implement design in C++.
*Verify model by comparing to real-world tests on the Crazyflie Swarm!
===Benefits===
*Improved flight control leading to more complex applications
*Maintain control without all the information (State Estimation)
*'''Potential Extension:''' Stable control with Stochastic lossy packet transmission
==Develop Communications Network Between Crazyflies==
===Focus Area===
'''Communication Networking and Firmware Development'''
*This project will require/develop a good understanding of network protocols and creating complex communications networks
===Tasks===
*Research the Crazy RealTime Protocol (CRTP) used by the Crazyflie
**[https://wiki.bitcraze.io/projects:crazyflie:firmware:comm_protocol CRTP Protocol]
**[https://github.com/bitcraze/crazyflie2-nrf-firmware/blob/master/src/esb.c Enhanced Shock Burst USB Radio Protocol]
*'''(HARD)''' Modify the Crazyflie Firmware to enable both transmit (tx) and receive (rx) packets
*'''(HARD)''' Develop a system in Firmware to utilize the bi-directional communications
**Example: Using the pitch, roll, or yaw of a Crazyflie to influence control of another Crazyflie(s) without passing it through the Swarm Client
===Benefits===
*Crazyflies can pass information between themselves
*Stepping stone to fully autonomous Crazyflie Swamrs (No Client needed)
*Opens up many possible extended applications
*'''Potential Extensions:'''
**Relative Swarm Formations (patterns based on distance from other members of the swarm, not some global entity)
**Create Advanced [[#Trilateration Position Estimation using a Swarm|Trilateration Localization]] using Swarm itself
==Trilateration Position Estimation using a Swarm==
===Focus Area===
'''Stochastic Lossy Networks and Localization Methods'''
*This project will develop a noise model for the Crazyflie communications in the lab and use that information to estimate an unknown Crazyflie's position.
===Tasks===
*Research Trilateration and Develop noise models for the Lab environment
**[https://iastate.box.com/s/kfmvun479t83fyp5mjntokdyq5rtx802 Simple Proof of Concept example]
**[https://iastate.box.com/s/34jf1ekow2wltun1qpsv3xighuaz4c0i Trilateration Matlab Code]
*'''(HARD)''' Develop Client-side sub-routine to collect Received Signal Strength Indicator (RSSI) value from each node (Crazyflie or USB Radio)
*'''(EASY)''' Develop Client-side sub-routine to calculate location estimate using RSSI based Trilateration method
*Use position estimate to maintain stable flight without the use of the Camera System
===Benefits===
*Stepping stone to Outdoor Localization (effective outdoor localization method complimentary with GPS)
*Reduces dependence on Camera System for localization
*'''Potential Extension:''' Relative Swarm Formations (position dependent on distance from other members of the swarm, rather than a 'global' origin)
----
<center> '''Main Directory''' </center>
<center> [[Crazyflie Swarm|Crazyflie Swarm Home]] | [[PC Client Software]] | [[USB Radio]] | [[Firmware]] | [[FAQ]] </center>
<center> '''Modifications Directory''' </center>
<center> [[Controller]] | [[Logging]] | [[Keyboard Commands]] | [[USB Radio#Changing Radio Channel|Changing Radio Channel]] | [[Flight Modes]] | [[Callbacks]] | [[Adding a Crazyflie]] | [[Firmware]] </center>
c661bea9009dbd06428e49f493100d66c9a7bc84
274
273
2016-08-03T19:33:01Z
Jnoronha
3
added big quad deck project
wikitext
text/x-wiki
Here we will go into more depth on what each of these projects would require:
==Migrating Swarm Client PID's to Firmware==
===Focus Area===
'''Firmware Programming and Communication Protocols'''
*This project requires heavy modification of the Firmware and Communication systems inside the Crazyflie.
===Tasks===
====Firmware====
*'''(HARD)''' Modifying [https://wiki.bitcraze.io/projects:crazyflie:crtp:commander Commander Packet Structure] to allow position data to be sent rather than pitch, roll, yaw, and thrust setpoints.
*Modifying Firmware to pass the new position data into the correct place for use by the Firmware PID controllers.
====Client====
*Modify Swarm Client packet construction to match new commander packet protocol in Firmware
*'''(EASY)''' Remove Controllers from callbacks and just send location packets to Crazyflies while still maintaining other functionality.
===Benefits===
*Significantly reduces Client-side computation and allows Crazyflie swarm to share the load.
*'''Potential extension:''' Completely independent Crazyflie flight (i.e. No Client needed at all)
==Model Development/Verification and Tuning X, Y, and Z Location PID's==
===Focus Area===
'''Control Systems and Model Development/Verification'''
*This project will require developing a model of the Crazyflie system and using the Model to calculate PID constants.
===Tasks===
*'''(HARD)''' Identify model Parameters for the Crazyflie
*Construct model in Simulink and Verify simulation compared to test data
*'''(EASY)''' Derive PID constants from verified model, test flight performance
===Benefits===
*'''VERIFIED MODEL!!''' We can do many things once we have a verified model of the system.
*Flight performance will be greatly improved allowing more complex applications to be developed.
*'''Potential extension:''' Path prediction algorithms and optimal pathing between points with obstacles
==Adding Parameter Support to Swarm Client==
===Focus Area===
'''Communications Protocols and Networking'''
*This project will require Client-side software development to create helper functions for easy modification of parameters on the Crazyflie Firmware
===Tasks===
*Creating packet framework in the Client to replicate the [https://wiki.bitcraze.io/projects:crazyflie:firmware:comm_protocol#parameters parameters packet protocol]
*Programming helper functions to make it simple to modify parameters
**Ex. Write Parameter Value: <code>setParam(string "param_group.param_name", int set_value);</code>
**Ex. Read Parameter Value: <code>readParam(string "param_group.param_name");</code>
===Benefits===
*Won't have to re-flash Firmware every time we want to test a parameter change (Improves Firmware testing efficiency)
*Less Firmware modification if we can just write params during Client init.
*'''Potential Extension:''' Tuning Firmware PID constants
==Threading Each USB Radio to speed up Computation==
===Focus Area===
'''Computer Architecture and Parallelization'''
*This project will require/develop a good understanding of parallel processing and computer architecture.
===Tasks===
*Apply threading to each USB Radio individually
**A single Radio will be assigned at most 3 Crazyflies, and each thread will handle the corresponding Callbacks for those Crazyflies (which includes control calculations, Radio communications, and logging for each Crazyflie)
*Troubleshoot any issues that come up with non-sequential program execution (shouldn't have problems)
===Benefits===
*Greatly reduces time required to complete a loop cycle (relative to number of Crazyflies in the Swarm)
**Improves scalability of the Swarm since we don't need to worry about missing the Camera System new data timing deadline as the Swarm size increases
*'''Potential Extension:''' Increasing Swarm size to Camera System capacity limit.
==Developing New Controllers for the Crazyflie (pending Model Development)==
===Focus Area===
'''Control System Development and Implementation'''
*This project will require a background in theoretical controls modeling and systems design.
===Tasks===
*Research Control Designs and decide which controller you want to use
**Examples: State Feedback Control (LQR, LQI, Pole Placement), State Space Controller (Lyapunov Estimator, H2), etc..
*Develop a Simulink model for the controller and implement design in C++.
*Verify model by comparing to real-world tests on the Crazyflie Swarm!
===Benefits===
*Improved flight control leading to more complex applications
*Maintain control without all the information (State Estimation)
*'''Potential Extension:''' Stable control with Stochastic lossy packet transmission
==Develop Communications Network Between Crazyflies==
===Focus Area===
'''Communication Networking and Firmware Development'''
*This project will require/develop a good understanding of network protocols and creating complex communications networks
===Tasks===
*Research the Crazy RealTime Protocol (CRTP) used by the Crazyflie
**[https://wiki.bitcraze.io/projects:crazyflie:firmware:comm_protocol CRTP Protocol]
**[https://github.com/bitcraze/crazyflie2-nrf-firmware/blob/master/src/esb.c Enhanced Shock Burst USB Radio Protocol]
*'''(HARD)''' Modify the Crazyflie Firmware to enable both transmit (tx) and receive (rx) packets
*'''(HARD)''' Develop a system in Firmware to utilize the bi-directional communications
**Example: Using the pitch, roll, or yaw of a Crazyflie to influence control of another Crazyflie(s) without passing it through the Swarm Client
===Benefits===
*Crazyflies can pass information between themselves
*Stepping stone to fully autonomous Crazyflie Swamrs (No Client needed)
*Opens up many possible extended applications
*'''Potential Extensions:'''
**Relative Swarm Formations (patterns based on distance from other members of the swarm, not some global entity)
**Create Advanced [[#Trilateration Position Estimation using a Swarm|Trilateration Localization]] using Swarm itself
==Trilateration Position Estimation using a Swarm==
===Focus Area===
'''Stochastic Lossy Networks and Localization Methods'''
*This project will develop a noise model for the Crazyflie communications in the lab and use that information to estimate an unknown Crazyflie's position.
===Tasks===
*Research Trilateration and Develop noise models for the Lab environment
**[https://iastate.box.com/s/kfmvun479t83fyp5mjntokdyq5rtx802 Simple Proof of Concept example]
**[https://iastate.box.com/s/34jf1ekow2wltun1qpsv3xighuaz4c0i Trilateration Matlab Code]
*'''(HARD)''' Develop Client-side sub-routine to collect Received Signal Strength Indicator (RSSI) value from each node (Crazyflie or USB Radio)
*'''(EASY)''' Develop Client-side sub-routine to calculate location estimate using RSSI based Trilateration method
*Use position estimate to maintain stable flight without the use of the Camera System
===Benefits===
*Stepping stone to Outdoor Localization (effective outdoor localization method complimentary with GPS)
*Reduces dependence on Camera System for localization
*'''Potential Extension:''' Relative Swarm Formations (position dependent on distance from other members of the swarm, rather than a 'global' origin)
==Extending Swarm Client to Larger Quadcopters==
----
<center> '''Main Directory''' </center>
<center> [[Crazyflie Swarm|Crazyflie Swarm Home]] | [[PC Client Software]] | [[USB Radio]] | [[Firmware]] | [[FAQ]] </center>
<center> '''Modifications Directory''' </center>
<center> [[Controller]] | [[Logging]] | [[Keyboard Commands]] | [[USB Radio#Changing Radio Channel|Changing Radio Channel]] | [[Flight Modes]] | [[Callbacks]] | [[Adding a Crazyflie]] | [[Firmware]] </center>
4e6084385d07b6bda89d7b469c81bedcc3a13ce9
275
274
2016-08-03T19:47:58Z
Jnoronha
3
finished BigQuad Deck section
wikitext
text/x-wiki
Here we will go into more depth on what each of these projects would require:
==Migrating Swarm Client PID's to Firmware==
===Focus Area===
'''Firmware Programming and Communication Protocols'''
*This project requires heavy modification of the Firmware and Communication systems inside the Crazyflie.
===Tasks===
====Firmware====
*'''(HARD)''' Modifying [https://wiki.bitcraze.io/projects:crazyflie:crtp:commander Commander Packet Structure] to allow position data to be sent rather than pitch, roll, yaw, and thrust setpoints.
*Modifying Firmware to pass the new position data into the correct place for use by the Firmware PID controllers.
====Client====
*Modify Swarm Client packet construction to match new commander packet protocol in Firmware
*'''(EASY)''' Remove Controllers from callbacks and just send location packets to Crazyflies while still maintaining other functionality.
===Benefits===
*Significantly reduces Client-side computation and allows Crazyflie swarm to share the load.
*'''Potential extension:''' Completely independent Crazyflie flight (i.e. No Client needed at all)
==Model Development/Verification and Tuning X, Y, and Z Location PID's==
===Focus Area===
'''Control Systems and Model Development/Verification'''
*This project will require developing a model of the Crazyflie system and using the Model to calculate PID constants.
===Tasks===
*'''(HARD)''' Identify model Parameters for the Crazyflie
*Construct model in Simulink and Verify simulation compared to test data
*'''(EASY)''' Derive PID constants from verified model, test flight performance
===Benefits===
*'''VERIFIED MODEL!!''' We can do many things once we have a verified model of the system.
*Flight performance will be greatly improved allowing more complex applications to be developed.
*'''Potential extension:''' Path prediction algorithms and optimal pathing between points with obstacles
==Adding Parameter Support to Swarm Client==
===Focus Area===
'''Communications Protocols and Networking'''
*This project will require Client-side software development to create helper functions for easy modification of parameters on the Crazyflie Firmware
===Tasks===
*Creating packet framework in the Client to replicate the [https://wiki.bitcraze.io/projects:crazyflie:firmware:comm_protocol#parameters parameters packet protocol]
*Programming helper functions to make it simple to modify parameters
**Ex. Write Parameter Value: <code>setParam(string "param_group.param_name", int set_value);</code>
**Ex. Read Parameter Value: <code>readParam(string "param_group.param_name");</code>
===Benefits===
*Won't have to re-flash Firmware every time we want to test a parameter change (Improves Firmware testing efficiency)
*Less Firmware modification if we can just write params during Client init.
*'''Potential Extension:''' Tuning Firmware PID constants
==Threading Each USB Radio to speed up Computation==
===Focus Area===
'''Computer Architecture and Parallelization'''
*This project will require/develop a good understanding of parallel processing and computer architecture.
===Tasks===
*Apply threading to each USB Radio individually
**A single Radio will be assigned at most 3 Crazyflies, and each thread will handle the corresponding Callbacks for those Crazyflies (which includes control calculations, Radio communications, and logging for each Crazyflie)
*Troubleshoot any issues that come up with non-sequential program execution (shouldn't have problems)
===Benefits===
*Greatly reduces time required to complete a loop cycle (relative to number of Crazyflies in the Swarm)
**Improves scalability of the Swarm since we don't need to worry about missing the Camera System new data timing deadline as the Swarm size increases
*'''Potential Extension:''' Increasing Swarm size to Camera System capacity limit.
==Developing New Controllers for the Crazyflie (pending Model Development)==
===Focus Area===
'''Control System Development and Implementation'''
*This project will require a background in theoretical controls modeling and systems design.
===Tasks===
*Research Control Designs and decide which controller you want to use
**Examples: State Feedback Control (LQR, LQI, Pole Placement), State Space Controller (Lyapunov Estimator, H2), etc..
*Develop a Simulink model for the controller and implement design in C++.
*Verify model by comparing to real-world tests on the Crazyflie Swarm!
===Benefits===
*Improved flight control leading to more complex applications
*Maintain control without all the information (State Estimation)
*'''Potential Extension:''' Stable control with Stochastic lossy packet transmission
==Develop Communications Network Between Crazyflies==
===Focus Area===
'''Communication Networking and Firmware Development'''
*This project will require/develop a good understanding of network protocols and creating complex communications networks
===Tasks===
*Research the Crazy RealTime Protocol (CRTP) used by the Crazyflie
**[https://wiki.bitcraze.io/projects:crazyflie:firmware:comm_protocol CRTP Protocol]
**[https://github.com/bitcraze/crazyflie2-nrf-firmware/blob/master/src/esb.c Enhanced Shock Burst USB Radio Protocol]
*'''(HARD)''' Modify the Crazyflie Firmware to enable both transmit (tx) and receive (rx) packets
*'''(HARD)''' Develop a system in Firmware to utilize the bi-directional communications
**Example: Using the pitch, roll, or yaw of a Crazyflie to influence control of another Crazyflie(s) without passing it through the Swarm Client
===Benefits===
*Crazyflies can pass information between themselves
*Stepping stone to fully autonomous Crazyflie Swamrs (No Client needed)
*Opens up many possible extended applications
*'''Potential Extensions:'''
**Relative Swarm Formations (patterns based on distance from other members of the swarm, not some global entity)
**Create Advanced [[#Trilateration Position Estimation using a Swarm|Trilateration Localization]] using Swarm itself
==Trilateration Position Estimation using a Swarm==
===Focus Area===
'''Stochastic Lossy Networks and Localization Methods'''
*This project will develop a noise model for the Crazyflie communications in the lab and use that information to estimate an unknown Crazyflie's position.
===Tasks===
*Research Trilateration and Develop noise models for the Lab environment
**[https://iastate.box.com/s/kfmvun479t83fyp5mjntokdyq5rtx802 Simple Proof of Concept example]
**[https://iastate.box.com/s/34jf1ekow2wltun1qpsv3xighuaz4c0i Trilateration Matlab Code]
*'''(HARD)''' Develop Client-side sub-routine to collect Received Signal Strength Indicator (RSSI) value from each node (Crazyflie or USB Radio)
*'''(EASY)''' Develop Client-side sub-routine to calculate location estimate using RSSI based Trilateration method
*Use position estimate to maintain stable flight without the use of the Camera System
===Benefits===
*Stepping stone to Outdoor Localization (effective outdoor localization method complimentary with GPS)
*Reduces dependence on Camera System for localization
*'''Potential Extension:''' Relative Swarm Formations (position dependent on distance from other members of the swarm, rather than a 'global' origin)
==Extending Swarm Client to Larger Quadcopters==
===Focus Area===
'''Hardware Development and System Modeling'''
*This project will utilize the [https://www.bitcraze.io/bigquad-deck/ Crazyflie's BigQuad Deck] Expansion board to convert the motor commands to signals for ESC motor controllers
===Tasks===
*Research the BigQuad Deck and the Crazyflie Client functionality
*Derive System Model and parameters for the large Quadcopter
*Develop a simple test bench for testing the motor command conversion safely
*Run Flight tests to validate the system model and stability of the scaled-up quadcopter
===Benefits===
*Allows other lab projects to utilize the Crazyflie's onboard 10-DOF (acc, gyro, mag, baro) sensors without the size, battery, and payload limitations of the Crazyflie!
*Use the Swarm Client Platform as a 'universal' backbone for lab projects.
*'''Potential Extension:''' Mount the Crazyflie onto ANY Quadcopter based application and program the Swarm Client to run the application.
----
<center> '''Main Directory''' </center>
<center> [[Crazyflie Swarm|Crazyflie Swarm Home]] | [[PC Client Software]] | [[USB Radio]] | [[Firmware]] | [[FAQ]] </center>
<center> '''Modifications Directory''' </center>
<center> [[Controller]] | [[Logging]] | [[Keyboard Commands]] | [[USB Radio#Changing Radio Channel|Changing Radio Channel]] | [[Flight Modes]] | [[Callbacks]] | [[Adding a Crazyflie]] | [[Firmware]] </center>
694841270203a916c55b7e47d5a3c2f1c02b25e2
276
275
2016-08-03T19:48:16Z
Jnoronha
3
fixed spacing of directory
wikitext
text/x-wiki
Here we will go into more depth on what each of these projects would require:
==Migrating Swarm Client PID's to Firmware==
===Focus Area===
'''Firmware Programming and Communication Protocols'''
*This project requires heavy modification of the Firmware and Communication systems inside the Crazyflie.
===Tasks===
====Firmware====
*'''(HARD)''' Modifying [https://wiki.bitcraze.io/projects:crazyflie:crtp:commander Commander Packet Structure] to allow position data to be sent rather than pitch, roll, yaw, and thrust setpoints.
*Modifying Firmware to pass the new position data into the correct place for use by the Firmware PID controllers.
====Client====
*Modify Swarm Client packet construction to match new commander packet protocol in Firmware
*'''(EASY)''' Remove Controllers from callbacks and just send location packets to Crazyflies while still maintaining other functionality.
===Benefits===
*Significantly reduces Client-side computation and allows Crazyflie swarm to share the load.
*'''Potential extension:''' Completely independent Crazyflie flight (i.e. No Client needed at all)
==Model Development/Verification and Tuning X, Y, and Z Location PID's==
===Focus Area===
'''Control Systems and Model Development/Verification'''
*This project will require developing a model of the Crazyflie system and using the Model to calculate PID constants.
===Tasks===
*'''(HARD)''' Identify model Parameters for the Crazyflie
*Construct model in Simulink and Verify simulation compared to test data
*'''(EASY)''' Derive PID constants from verified model, test flight performance
===Benefits===
*'''VERIFIED MODEL!!''' We can do many things once we have a verified model of the system.
*Flight performance will be greatly improved allowing more complex applications to be developed.
*'''Potential extension:''' Path prediction algorithms and optimal pathing between points with obstacles
==Adding Parameter Support to Swarm Client==
===Focus Area===
'''Communications Protocols and Networking'''
*This project will require Client-side software development to create helper functions for easy modification of parameters on the Crazyflie Firmware
===Tasks===
*Creating packet framework in the Client to replicate the [https://wiki.bitcraze.io/projects:crazyflie:firmware:comm_protocol#parameters parameters packet protocol]
*Programming helper functions to make it simple to modify parameters
**Ex. Write Parameter Value: <code>setParam(string "param_group.param_name", int set_value);</code>
**Ex. Read Parameter Value: <code>readParam(string "param_group.param_name");</code>
===Benefits===
*Won't have to re-flash Firmware every time we want to test a parameter change (Improves Firmware testing efficiency)
*Less Firmware modification if we can just write params during Client init.
*'''Potential Extension:''' Tuning Firmware PID constants
==Threading Each USB Radio to speed up Computation==
===Focus Area===
'''Computer Architecture and Parallelization'''
*This project will require/develop a good understanding of parallel processing and computer architecture.
===Tasks===
*Apply threading to each USB Radio individually
**A single Radio will be assigned at most 3 Crazyflies, and each thread will handle the corresponding Callbacks for those Crazyflies (which includes control calculations, Radio communications, and logging for each Crazyflie)
*Troubleshoot any issues that come up with non-sequential program execution (shouldn't have problems)
===Benefits===
*Greatly reduces time required to complete a loop cycle (relative to number of Crazyflies in the Swarm)
**Improves scalability of the Swarm since we don't need to worry about missing the Camera System new data timing deadline as the Swarm size increases
*'''Potential Extension:''' Increasing Swarm size to Camera System capacity limit.
==Developing New Controllers for the Crazyflie (pending Model Development)==
===Focus Area===
'''Control System Development and Implementation'''
*This project will require a background in theoretical controls modeling and systems design.
===Tasks===
*Research Control Designs and decide which controller you want to use
**Examples: State Feedback Control (LQR, LQI, Pole Placement), State Space Controller (Lyapunov Estimator, H2), etc..
*Develop a Simulink model for the controller and implement design in C++.
*Verify model by comparing to real-world tests on the Crazyflie Swarm!
===Benefits===
*Improved flight control leading to more complex applications
*Maintain control without all the information (State Estimation)
*'''Potential Extension:''' Stable control with Stochastic lossy packet transmission
==Develop Communications Network Between Crazyflies==
===Focus Area===
'''Communication Networking and Firmware Development'''
*This project will require/develop a good understanding of network protocols and creating complex communications networks
===Tasks===
*Research the Crazy RealTime Protocol (CRTP) used by the Crazyflie
**[https://wiki.bitcraze.io/projects:crazyflie:firmware:comm_protocol CRTP Protocol]
**[https://github.com/bitcraze/crazyflie2-nrf-firmware/blob/master/src/esb.c Enhanced Shock Burst USB Radio Protocol]
*'''(HARD)''' Modify the Crazyflie Firmware to enable both transmit (tx) and receive (rx) packets
*'''(HARD)''' Develop a system in Firmware to utilize the bi-directional communications
**Example: Using the pitch, roll, or yaw of a Crazyflie to influence control of another Crazyflie(s) without passing it through the Swarm Client
===Benefits===
*Crazyflies can pass information between themselves
*Stepping stone to fully autonomous Crazyflie Swamrs (No Client needed)
*Opens up many possible extended applications
*'''Potential Extensions:'''
**Relative Swarm Formations (patterns based on distance from other members of the swarm, not some global entity)
**Create Advanced [[#Trilateration Position Estimation using a Swarm|Trilateration Localization]] using Swarm itself
==Trilateration Position Estimation using a Swarm==
===Focus Area===
'''Stochastic Lossy Networks and Localization Methods'''
*This project will develop a noise model for the Crazyflie communications in the lab and use that information to estimate an unknown Crazyflie's position.
===Tasks===
*Research Trilateration and Develop noise models for the Lab environment
**[https://iastate.box.com/s/kfmvun479t83fyp5mjntokdyq5rtx802 Simple Proof of Concept example]
**[https://iastate.box.com/s/34jf1ekow2wltun1qpsv3xighuaz4c0i Trilateration Matlab Code]
*'''(HARD)''' Develop Client-side sub-routine to collect Received Signal Strength Indicator (RSSI) value from each node (Crazyflie or USB Radio)
*'''(EASY)''' Develop Client-side sub-routine to calculate location estimate using RSSI based Trilateration method
*Use position estimate to maintain stable flight without the use of the Camera System
===Benefits===
*Stepping stone to Outdoor Localization (effective outdoor localization method complimentary with GPS)
*Reduces dependence on Camera System for localization
*'''Potential Extension:''' Relative Swarm Formations (position dependent on distance from other members of the swarm, rather than a 'global' origin)
==Extending Swarm Client to Larger Quadcopters==
===Focus Area===
'''Hardware Development and System Modeling'''
*This project will utilize the [https://www.bitcraze.io/bigquad-deck/ Crazyflie's BigQuad Deck] Expansion board to convert the motor commands to signals for ESC motor controllers
===Tasks===
*Research the BigQuad Deck and the Crazyflie Client functionality
*Derive System Model and parameters for the large Quadcopter
*Develop a simple test bench for testing the motor command conversion safely
*Run Flight tests to validate the system model and stability of the scaled-up quadcopter
===Benefits===
*Allows other lab projects to utilize the Crazyflie's onboard 10-DOF (acc, gyro, mag, baro) sensors without the size, battery, and payload limitations of the Crazyflie!
*Use the Swarm Client Platform as a 'universal' backbone for lab projects.
*'''Potential Extension:''' Mount the Crazyflie onto ANY Quadcopter based application and program the Swarm Client to run the application.
----
<center> '''Main Directory''' </center>
<center> [[Crazyflie Swarm|Crazyflie Swarm Home]] | [[PC Client Software]] | [[USB Radio]] | [[Firmware]] | [[FAQ]] </center>
<center> '''Modifications Directory''' </center>
<center> [[Controller]] | [[Logging]] | [[Keyboard Commands]] | [[USB Radio#Changing Radio Channel|Changing Radio Channel]] | [[Flight Modes]] | [[Callbacks]] | [[Adding a Crazyflie]] | [[Firmware]] </center>
48f7221222d9292c4cf370f14d2093dffb5e67a4
File:CrazyflieFirmwareArchitecture.png
6
80
270
2016-08-03T18:45:06Z
Jnoronha
3
Block diagram of the Crazyflie Firmware system
wikitext
text/x-wiki
Block diagram of the Crazyflie Firmware system
1436e30dbf2b6e69a5a543da6b8ea008c52c51d6
297
270
2016-08-27T17:44:32Z
Jnoronha
3
Jnoronha uploaded a new version of [[File:CrazyflieFirmwareArchitecture.png]]
wikitext
text/x-wiki
Block diagram of the Crazyflie Firmware system
1436e30dbf2b6e69a5a543da6b8ea008c52c51d6
Firmware
0
26
271
248
2016-08-03T18:48:26Z
Jnoronha
3
added firmware architecture and separated sections
wikitext
text/x-wiki
The Firmware architecture layout:
[[Image:CrazyflieFirmwareArchitecture.png|700px]]
[https://www.bitcraze.io/2015/01/crazyflie-2-0-radio-communication/ Crazyflie Firmware Architecture Layout]
==Firmware Modifications==
Not much work has been done in the Firmware yet (as of 7/20/16). The few things we have been able to successfully modify are:
#Creating New Log Blocks
#Modifying the Default Yaw Mode
#Adding and Modifying Parameter Values
==New Firmware Log Blocks==
In the Crazyflie Firmware there is a generalized logging framework that allows us to make any group of variables into a log block. It makes things very easy to log. Here are a few examples:
:'''IMPORTANT:''' If you want to create new Log groups in a file, make sure you include <code>#include "log.h"</code> at the top of the file.
:Ex. 1. Magnometer Log Block (code found in ''Firmware > modules > src > stabilizer.c'')
<blockquote>
<code>
<pre>
LOG_GROUP_START(mag)
LOG_ADD(LOG_FLOAT, x, &mag.x)
LOG_ADD(LOG_FLOAT, y, &mag.y)
LOG_ADD(LOG_FLOAT, z, &mag.z)
LOG_GROUP_STOP(mag)
</pre>
</code>
</blockquote>
::So with this code we have created a log block called 'mag' and it contains the X, Y, and Z measurements from the magnetometer sensor.
:Ex. 2. Accelerometer Log Block (code found in ''Firmware > modules > src > stabilizer.c'')
<blockquote>
<code>
<pre>
LOG_GROUP_START(acc)
LOG_ADD(LOG_FLOAT, x, &acc.x)
LOG_ADD(LOG_FLOAT, y, &acc.y)
LOG_ADD(LOG_FLOAT, z, &acc.z)
LOG_ADD(LOG_FLOAT, zw, &accWZ)
LOG_ADD(LOG_FLOAT, mag2, &accMAG)
LOG_GROUP_STOP(acc)
</pre>
</code>
</blockquote>
::Just like in the magnetometer block, here we have created a log group called 'acc' and inside this group we are logging the variables for the accelerometer's X, Y, and Z values as well as 2 other gravity based variables used for thrust compensation.
===Using New Log Blocks in Swarm Client===
Now that we have these new log blocks in the Firmware, we can [[:Logging#New Client Log Blocks|use log blocks in the Client]]
==Modify the Default Yaw Mode==
There are 3 types of Yaw Modes available in the Firmware (as of 7/21/16), as shown (code in ''Firmware > modules > interface > commander.h'')
<blockquote>
<code>
<pre>
typedef enum
{
CAREFREE = 0, // Yaw is locked to world coordinates thus heading stays the same when yaw rotates
PLUSMODE = 1, // Plus-mode. Motor M1 is defined as front
XMODE = 2, // X-mode. M1 & M4 is defined as front
} YawModeType;
</pre>
</code>
</blockquote>
:'''Note:''' The default mode for the Crazyflie 2.0 is ''XMODE''. The ''PLUSMODE'' is default for the Crazyflie 1.0, but can still be used on the Crazyflie 2.0 if desired.
===Carefree Mode===
''CAREFREE'' mode is what our Crazyflie 2.0's are using, this mode applies a transformation to the Pitch and Roll setpoints depending on the angle of Yaw. We used to perform this calculation on the Client like this (code in ''eris_vrpn.cpp''):
<blockquote>
<code>
<pre>
#if USE_PR_YAW_CORRECT
//CORRECTS PITCH AND ROLL PID ERRORS TO ACCOUNT FOR QUADS CURRENT YAW DIRECTION (_/57.2958 converts DEG to RADIANS)
xError2 = cos(correctedYaw2 / 57.2958)*(xPositionDesired2 - xPosition2) - sin(correctedYaw2 / 57.2958)*(yPositionDesired2 - yPosition2);
yError2 = sin(correctedYaw2 / 57.2958)*(xPositionDesired2 - xPosition2) + cos(correctedYaw2 / 57.2958)*(yPositionDesired2 - yPosition2);
#else
xError2 = xPositionDesired2 - xPosition2;
yError2 = yPositionDesired2 - yPosition2;
#endif
controllerSetXYError(&pidCtrl2, xError2, yError2);
</pre>
</code>
</blockquote>
This is no longer necessary on the Client because this is the exact same calculation ''CAREFREE'' mode performs on the Firmware. So this reduces the computation done on the Client in each Crazyflie Callback.
====Changing Yaw Mode in Firmware====
To change the Yaw Mode to ''CAREFREE'' mode we had to make the modification shown (code in ''Firmware > modules > interface > commander.h (line 36)''):
:'''ORIGINAL:'''
<blockquote>
<code>
<pre>
...
#ifdef PLATFORM_CF1
#define DEFUALT_YAW_MODE PLUSMODE
#else
#define DEFUALT_YAW_MODE XMODE
#endif
...
</pre>
</code>
</blockquote>
:'''MODIFIED:'''
<blockquote>
<code>
<pre>
...
#ifdef PLATFORM_CF1
#define DEFUALT_YAW_MODE PLUSMODE
#else
#define DEFUALT_YAW_MODE CAREFREE
#endif
...
</pre>
</code>
</blockquote>
::The code checks for which version Crazyflie you are using, either the original Crazyflie (<code>PLATFORM_CF1</code>), or the Crazyflie 2.0. We are using the Crazyflie 2.0 so we only care about the 2nd ''DEFAULT_YAW_MODE'', which we modified to ''CAREFREE'' mode as shown.
==New Firmware Parameter Groups==
Parameter groups are very similar to Log groups with a few key differences. An example of a Parameter group is shown (code in ''Firmware > modules > src > commander.c''):
:'''IMPORTANT:''' If you want to create new Parameter groups in a file, make sure you include <code>#include "param.h"</code> at the top of the file.
<blockquote>
<code>
<pre>
// Params for flight modes
PARAM_GROUP_START(flightmode)
PARAM_ADD(PARAM_UINT8, althold, &altHoldMode)
PARAM_ADD(PARAM_UINT8, yawMode, &yawMode)
PARAM_ADD(PARAM_UINT8, yawRst, &carefreeResetFront)
PARAM_ADD(PARAM_UINT8, stabModeRoll, &stabilizationModeRoll)
PARAM_ADD(PARAM_UINT8, stabModePitch, &stabilizationModePitch)
PARAM_ADD(PARAM_UINT8, stabModeYaw, &stabilizationModeYaw)
PARAM_GROUP_STOP(flightmode)
</pre>
</code>
</blockquote>
:So we create a parameter group called ''flightmode'' that contains the parameters listed. The difference between Log variables and Param variables is that for Param variables you need to specify the variable type (''PARAM_UINT8'' shown in the example).
Some User Friendly Param Types are shown below (you can find more complex Param types in ''Firmware > modules > interface > param.h'').
<blockquote>
<code>
<pre>
// User-friendly macros
#define PARAM_UINT8 (PARAM_1BYTE | PARAM_TYPE_INT | PARAM_UNSIGNED)
#define PARAM_INT8 (PARAM_1BYTE | PARAM_TYPE_INT | PARAM_SIGNED)
#define PARAM_UINT16 (PARAM_2BYTES | PARAM_TYPE_INT | PARAM_UNSIGNED)
#define PARAM_INT16 (PARAM_2BYTES | PARAM_TYPE_INT | PARAM_SIGNED)
#define PARAM_UINT32 (PARAM_4BYTES | PARAM_TYPE_INT | PARAM_UNSIGNED)
#define PARAM_INT32 (PARAM_4BYTES | PARAM_TYPE_INT | PARAM_SIGNED)
</pre>
</code>
</blockquote>
===Using Param Groups in Client===
This is not implemented yet (as of 7/21/16) but would be very nice to have. We could then tune Firmware PID constants without needing to flash the Firmware each time and much more.
If someone would like to [[:Future Project Ideas#Adding Parameter Support to Swarm Client|attempt to create this]] you can see the Bitcraze Wiki page on the [https://wiki.bitcraze.io/doc:crazyflie:crtp:param Params Protocol] for help on how to implement this.
----
<center> '''Main Directory''' </center>
<center> [[Crazyflie Swarm|Crazyflie Swarm Home]] | [[PC Client Software]] | [[USB Radio]] | [[Firmware]] | [[FAQ]] </center>
<center> '''Modifications Directory''' </center>
<center> [[Controller]] | [[Logging]] | [[Keyboard Commands]] | [[USB Radio#Changing Radio Channel|Changing Radio Channel]] | [[Flight Modes]] | [[Callbacks]] | [[Adding a Crazyflie]] | [[Firmware]] </center>
23d1ea28d6da0d947fb24451a0af41c7d44e143a
Setting up and Modifying RADA Simulations
0
81
277
2016-08-03T19:55:06Z
Pfuhing
5
New page: == Simulink Setup == === Setting up the MATLAB Workspace === === Settings in Simulink === === Store Data from Simulink === == Understanding and Modifying RADA Simulations == === Compo...
wikitext
text/x-wiki
== Simulink Setup ==
=== Setting up the MATLAB Workspace ===
=== Settings in Simulink ===
=== Store Data from Simulink ===
== Understanding and Modifying RADA Simulations ==
=== Components of the Model ===
==== Body dynamics calculations ====
==== Actuator dynamics calculations ====
==== System commands ====
==== Body velocity calculations ====
=== Modifying Simulink ===
==== Creating a new simulation ====
==== Modifying existing files ====
89afcaa7a4a1db7b4509badb5d124a9e4e2062f2
284
277
2016-08-04T19:56:41Z
Pfuhing
5
wikitext
text/x-wiki
== Simulink Setup ==
In order to use Simulink effectively you need to setup a few things. Iowa State will allow you download MATLAB and use a site license for free as a student. For more information about installing MATLAB using this site license look [http://it.engineering.iastate.edu/how-to/installing-matlab/ here.]
=== Setting up the MATLAB Workspace ===
=== Settings in Simulink ===
=== Store Data from Simulink ===
== Understanding and Modifying RADA Simulations ==
=== Components of the Model ===
==== Body dynamics calculations ====
==== Actuator dynamics calculations ====
==== System commands ====
==== Body velocity calculations ====
=== Modifying Simulink ===
==== Creating a new simulation ====
==== Modifying existing files ====
4f6e65f323061f72bef0e73f8cfa33058d40d9b2
285
284
2016-08-04T20:26:56Z
Pfuhing
5
wikitext
text/x-wiki
== Simulink Setup ==
In order to use Simulink effectively you need to setup a few things. Iowa State will allow you download MATLAB and use a site license for free as a student. For more information about installing MATLAB using this site license look [http://it.engineering.iastate.edu/how-to/installing-matlab/ here.] Simulink comes with MATLAB. You should get MATLAB 2014b or latter to ensure the Simulink files from Paul Uhing's research repository will work with your installation of MATLAB.
Once the install is complete and MATLAB is registered you can open MATLAB up. Then change the folder MATLAB will work out of to a directory you will want to work form. It would be best to copy a few files from Paul Uhing's repository to help you get started. Inside of the RADA Research Repository go to ''MATLAB/RADA'' and copy ''modelParams_smallWheels_RADA.m'', ''Hbrigeest.mat'', ''Kvw_calc.mat'', ''Hmu_r_erisLargeWheels.mat'', ''LQI_recalc.m'', and ''RADA_ctrlSep.m'' from this directory to you new diectroy as these files will allow you to load the model parameters and controller designs used in Paul Uhing's thesis or find the most recent version of these files an copy them instead. It would also be good to copy and of the ''RADA_psiCtrl_v2.slx'' or ''RADA_psiCtrl_LQGsep.slx'' files here to sever as the base RADA simulation in your new directory. Finally, open te ''DataSets'' directory below the ''RADA'' directory can copy one of the ''RADA_LQG_compPID.mat'' files or ''RADA_LQG_sep.mat'' files because it will allow you to have input vector for the copied ''.slx'' Simulink file.
=== Setting up the MATLAB Workspace ===
Now in MATLAB with you working directory set to you new directory for test RADA simulations run ''modelParams_smallWheels_RADA.m'' from the MATLAB command line ten load the RADA ''.mat'' data file. Now in the Current Folder screen in MATLAB double click on the ''.slx'' and wait for it to open.
=== Settings in Simulink ===
When running a simulation RADA in simulink always make sure your solver is set to '''ode23t'''! The RADA model is a moderately stiff set of differential equations and ode45 the default solver will take an extremely long time to run simulaitons of RADA. You can set the run length to any length you want and then run the simulation.
=== Store Data from Simulink ===
All of the Simulink files in Paul Uhing's Research Repository output simulation data MATLAB structures contain the time and value arrays for important variables. After a simulation finishes these will show up as variables in the MATLAB Workspace. If you want to save any of these values for latter use select them in the MATLAB Workspace and right-click and select save or press ctrl+s to save these varable to a ''.mat'' file.
== Understanding and Modifying RADA Simulations ==
=== Components of the Model ===
==== Body dynamics calculations ====
==== Actuator dynamics calculations ====
==== System commands ====
==== Body velocity calculations ====
=== Modifying Simulink ===
==== Creating a new simulation ====
==== Modifying existing files ====
518fa09ad10aad8cabc5095e70150e812aa257fb
286
285
2016-08-08T16:42:51Z
Pfuhing
5
wikitext
text/x-wiki
== Simulink Setup ==
In order to use Simulink effectively you need to setup a few things. Iowa State will allow you download MATLAB and use a site license for free as a student. For more information about installing MATLAB using this site license look [http://it.engineering.iastate.edu/how-to/installing-matlab/ here.] Simulink comes with MATLAB. You should get MATLAB 2014b or latter to ensure the Simulink files from Paul Uhing's research repository will work with your installation of MATLAB.
Once the install is complete and MATLAB is registered you can open MATLAB up. Then change the folder MATLAB will work out of to a directory you will want to work form. It would be best to copy a few files from Paul Uhing's repository to help you get started. Inside of the RADA Research Repository go to ''MATLAB/RADA'' and copy ''modelParams_smallWheels_RADA.m'', ''Hbrigeest.mat'', ''Kvw_calc.mat'', ''Hmu_r_erisLargeWheels.mat'', ''LQI_recalc.m'', and ''RADA_ctrlSep.m'' from this directory to you new diectroy as these files will allow you to load the model parameters and controller designs used in Paul Uhing's thesis or find the most recent version of these files an copy them instead. It would also be good to copy and of the ''RADA_psiCtrl_v2.slx'' or ''RADA_psiCtrl_LQGsep.slx'' files here to sever as the base RADA simulation in your new directory. Finally, open te ''DataSets'' directory below the ''RADA'' directory can copy one of the ''RADA_LQG_compPID.mat'' files or ''RADA_LQG_sep.mat'' files because it will allow you to have input vector for the copied ''.slx'' Simulink file.
=== Setting up the MATLAB Workspace ===
Now in MATLAB with you working directory set to you new directory for test RADA simulations run ''modelParams_smallWheels_RADA.m'' from the MATLAB command line ten load the RADA ''.mat'' data file. Now in the Current Folder screen in MATLAB double click on the ''.slx'' and wait for it to open.
=== Settings in Simulink ===
When running a simulation RADA in simulink always make sure your solver is set to '''ode23t'''! The RADA model is a moderately stiff set of differential equations and ode45 the default solver will take an extremely long time to run simulaitons of RADA. You can set the run length to any length you want and then run the simulation.
=== Store Data from Simulink ===
All of the Simulink files in Paul Uhing's Research Repository output simulation data MATLAB structures contain the time and value arrays for important variables. After a simulation finishes these will show up as variables in the MATLAB Workspace. If you want to save any of these values for latter use select them in the MATLAB Workspace and right-click and select save or press ctrl+s to save these variables to a ''.mat'' file.
== Understanding and Modifying RADA Simulations ==
The Simulink models of RADA for Paul Uhing's Thesis is built to be fairly easy to understand. Normal Simulink blocks are used for routing signals and completing simple calculations. For more difficult calculations MATLAB Function blocks are used. These blocks allow you to write MATLAB code to complete some calculation. They can have inputs from the Simulink simulation and parameter inputs from the MATLAB Workspace. This makes complex calculations much easier to understand. The goal of using all of these tricks is to avoid creating a model that is a rat's nest of interconnecting blocks that is impossible trace any errors in the simulation. Understanding how the RADA model was put together wil help you understand how to modify this model and how to build your own models.
=== Components of the Model ===
The model is broken down into subsystems based off of sub-components of the actual system. There is a block for calculating the accelerations of RADA's body, two blocks for calculating the different actuator sets, producing commands to the system, and calculating intermediate values used by other blocks.
==== Body dynamics calculations ====
The body dynamics block (''RADA_BodyDynamcis_v2'') takes in Euler angle position and velocity of the pendulum (including yaw), the global velocity of the ground vehicle, the force produced by the propellers in the x body direction of the pendulum, the force produced by the propellers in the y body direction of the pendulum, and the force produced by each wheel. This block is a MATLAB Function block so it also has parameter inputs. For using MATLAB Function block is is important to never delete:
%#codegen
because this allows the MATLAB code to function in Simulink.
The code inside the block is just the implementation of the final equation in Chapter 3.4 of Paul Uhing's Thesis. The outputs of the block are the acceleration of the pendulum's in pitch and roll, the acceleration of the yaw of the system, and the x and y global acceleration of the ground robot. Then MATLAB continuous time integrator blocks are used to get the corresponding velocities and positions. MATLAB function blocks do not do integration very well so it is easier just to calculate the accelerations and then use the Simulink blocks to integrate.
==== Actuator dynamics calculations ====
==== System commands ====
==== Body velocity calculations ====
=== Modifying Simulink ===
==== Creating a new simulation ====
==== Modifying existing files ====
64bb9f1a930a672550f5c37e48ada168da6b2cc6
287
286
2016-08-08T17:29:31Z
Pfuhing
5
/* Actuator dynamics calculations */
wikitext
text/x-wiki
== Simulink Setup ==
In order to use Simulink effectively you need to setup a few things. Iowa State will allow you download MATLAB and use a site license for free as a student. For more information about installing MATLAB using this site license look [http://it.engineering.iastate.edu/how-to/installing-matlab/ here.] Simulink comes with MATLAB. You should get MATLAB 2014b or latter to ensure the Simulink files from Paul Uhing's research repository will work with your installation of MATLAB.
Once the install is complete and MATLAB is registered you can open MATLAB up. Then change the folder MATLAB will work out of to a directory you will want to work form. It would be best to copy a few files from Paul Uhing's repository to help you get started. Inside of the RADA Research Repository go to ''MATLAB/RADA'' and copy ''modelParams_smallWheels_RADA.m'', ''Hbrigeest.mat'', ''Kvw_calc.mat'', ''Hmu_r_erisLargeWheels.mat'', ''LQI_recalc.m'', and ''RADA_ctrlSep.m'' from this directory to you new diectroy as these files will allow you to load the model parameters and controller designs used in Paul Uhing's thesis or find the most recent version of these files an copy them instead. It would also be good to copy and of the ''RADA_psiCtrl_v2.slx'' or ''RADA_psiCtrl_LQGsep.slx'' files here to sever as the base RADA simulation in your new directory. Finally, open te ''DataSets'' directory below the ''RADA'' directory can copy one of the ''RADA_LQG_compPID.mat'' files or ''RADA_LQG_sep.mat'' files because it will allow you to have input vector for the copied ''.slx'' Simulink file.
=== Setting up the MATLAB Workspace ===
Now in MATLAB with you working directory set to you new directory for test RADA simulations run ''modelParams_smallWheels_RADA.m'' from the MATLAB command line ten load the RADA ''.mat'' data file. Now in the Current Folder screen in MATLAB double click on the ''.slx'' and wait for it to open.
=== Settings in Simulink ===
When running a simulation RADA in simulink always make sure your solver is set to '''ode23t'''! The RADA model is a moderately stiff set of differential equations and ode45 the default solver will take an extremely long time to run simulaitons of RADA. You can set the run length to any length you want and then run the simulation.
=== Store Data from Simulink ===
All of the Simulink files in Paul Uhing's Research Repository output simulation data MATLAB structures contain the time and value arrays for important variables. After a simulation finishes these will show up as variables in the MATLAB Workspace. If you want to save any of these values for latter use select them in the MATLAB Workspace and right-click and select save or press ctrl+s to save these variables to a ''.mat'' file.
== Understanding and Modifying RADA Simulations ==
The Simulink models of RADA for Paul Uhing's Thesis is built to be fairly easy to understand. Normal Simulink blocks are used for routing signals and completing simple calculations. For more difficult calculations MATLAB Function blocks are used. These blocks allow you to write MATLAB code to complete some calculation. They can have inputs from the Simulink simulation and parameter inputs from the MATLAB Workspace. This makes complex calculations much easier to understand. The goal of using all of these tricks is to avoid creating a model that is a rat's nest of interconnecting blocks that is impossible trace any errors in the simulation. Understanding how the RADA model was put together wil help you understand how to modify this model and how to build your own models.
=== Components of the Model ===
The model is broken down into subsystems based off of sub-components of the actual system. There is a block for calculating the accelerations of RADA's body, two blocks for calculating the different actuator sets, producing commands to the system, and calculating intermediate values used by other blocks.
==== Body dynamics calculations ====
The body dynamics block (''RADA_BodyDynamcis_v2'') takes in Euler angle position and velocity of the pendulum (including yaw), the global velocity of the ground vehicle, the force produced by the propellers in the x body direction of the pendulum, the force produced by the propellers in the y body direction of the pendulum, and the force produced by each wheel. This block is a MATLAB Function block so it also has parameter inputs. For using MATLAB Function block is is important to never delete:
%#codegen
because this allows the MATLAB code to function in Simulink.
The code inside the block is just the implementation of the final equation in Chapter 3.4 of Paul Uhing's Thesis. The outputs of the block are the acceleration of the pendulum's in pitch and roll, the acceleration of the yaw of the system, and the x and y global acceleration of the ground robot. Then MATLAB continuous time integrator blocks are used to get the corresponding velocities and positions. MATLAB function blocks do not do integration very well so it is easier just to calculate the accelerations and then use the Simulink blocks to integrate.
== Simulink Setup ==
In order to use Simulink effectively you need to setup a few things. Iowa State will allow you download MATLAB and use a site license for free as a student. For more information about installing MATLAB using this site license look [http://it.engineering.iastate.edu/how-to/installing-matlab/ here.] Simulink comes with MATLAB. You should get MATLAB 2014b or latter to ensure the Simulink files from Paul Uhing's research repository will work with your installation of MATLAB.
Once the install is complete and MATLAB is registered you can open MATLAB up. Then change the folder MATLAB will work out of to a directory you will want to work form. It would be best to copy a few files from Paul Uhing's repository to help you get started. Inside of the RADA Research Repository go to ''MATLAB/RADA'' and copy ''modelParams_smallWheels_RADA.m'', ''Hbrigeest.mat'', ''Kvw_calc.mat'', ''Hmu_r_erisLargeWheels.mat'', ''LQI_recalc.m'', and ''RADA_ctrlSep.m'' from this directory to you new diectroy as these files will allow you to load the model parameters and controller designs used in Paul Uhing's thesis or find the most recent version of these files an copy them instead. It would also be good to copy and of the ''RADA_psiCtrl_v2.slx'' or ''RADA_psiCtrl_LQGsep.slx'' files here to sever as the base RADA simulation in your new directory. Finally, open te ''DataSets'' directory below the ''RADA'' directory can copy one of the ''RADA_LQG_compPID.mat'' files or ''RADA_LQG_sep.mat'' files because it will allow you to have input vector for the copied ''.slx'' Simulink file.
=== Setting up the MATLAB Workspace ===
Now in MATLAB with you working directory set to you new directory for test RADA simulations run ''modelParams_smallWheels_RADA.m'' from the MATLAB command line ten load the RADA ''.mat'' data file. Now in the Current Folder screen in MATLAB double click on the ''.slx'' and wait for it to open.
=== Settings in Simulink ===
When running a simulation RADA in simulink always make sure your solver is set to '''ode23t'''! The RADA model is a moderately stiff set of differential equations and ode45 the default solver will take an extremely long time to run simulaitons of RADA. You can set the run length to any length you want and then run the simulation.
=== Store Data from Simulink ===
All of the Simulink files in Paul Uhing's Research Repository output simulation data MATLAB structures contain the time and value arrays for important variables. After a simulation finishes these will show up as variables in the MATLAB Workspace. If you want to save any of these values for latter use select them in the MATLAB Workspace and right-click and select save or press ctrl+s to save these variables to a ''.mat'' file.
== Understanding and Modifying RADA Simulations ==
The Simulink models of RADA for Paul Uhing's Thesis is built to be fairly easy to understand. Normal Simulink blocks are used for routing signals and completing simple calculations. For more difficult calculations MATLAB Function blocks are used. These blocks allow you to write MATLAB code to complete some calculation. They can have inputs from the Simulink simulation and parameter inputs from the MATLAB Workspace. This makes complex calculations much easier to understand. The goal of using all of these tricks is to avoid creating a model that is a rat's nest of interconnecting blocks that is impossible trace any errors in the simulation. Understanding how the RADA model was put together wil help you understand how to modify this model and how to build your own models.
=== Components of the Model ===
The model is broken down into subsystems based off of sub-components of the actual system. There is a block for calculating the accelerations of RADA's body, two blocks for calculating the different actuator sets, producing commands to the system, and calculating intermediate values used by other blocks.
==== Body dynamics calculations ====
The body dynamics block (''RADA_BodyDynamcis_v2'') takes in Euler angle position and velocity of the pendulum (including yaw), the global velocity of the ground vehicle, the force produced by the propellers in the x body direction of the pendulum, the force produced by the propellers in the y body direction of the pendulum, and the force produced by each wheel. This block is a MATLAB Function block so it also has parameter inputs. For using MATLAB Function block is is important to never delete:
%#codegen
because this allows the MATLAB code to function in Simulink.
The code inside the block is just the implementation of the final equation in Chapter 3.4 of Paul Uhing's Thesis. The outputs of the block are the acceleration of the pendulum's in pitch and roll, the acceleration of the yaw of the system, and the x and y global acceleration of the ground robot. Then MATLAB continuous time integrator blocks are used to get the corresponding velocities and positions. MATLAB function blocks do not do integration very well so it is easier just to calculate the accelerations and then use the Simulink blocks to integrate.
==== Actuator dynamics calculations ====
==== System commands ====
==== Body velocity calculations ====
=== Modifying Simulink ===
==== Creating a new simulation ====
==== Modifying existing files ====
==== System commands ====
==== Body velocity calculations ====
=== Modifying Simulink ===
==== Creating a new simulation ====
==== Modifying existing files ====
e1f4037393136571e48d31a560777f1ef493b0b5
288
287
2016-08-08T17:30:33Z
Pfuhing
5
/* Actuator dynamics calculations */
wikitext
text/x-wiki
== Simulink Setup ==
In order to use Simulink effectively you need to setup a few things. Iowa State will allow you download MATLAB and use a site license for free as a student. For more information about installing MATLAB using this site license look [http://it.engineering.iastate.edu/how-to/installing-matlab/ here.] Simulink comes with MATLAB. You should get MATLAB 2014b or latter to ensure the Simulink files from Paul Uhing's research repository will work with your installation of MATLAB.
Once the install is complete and MATLAB is registered you can open MATLAB up. Then change the folder MATLAB will work out of to a directory you will want to work form. It would be best to copy a few files from Paul Uhing's repository to help you get started. Inside of the RADA Research Repository go to ''MATLAB/RADA'' and copy ''modelParams_smallWheels_RADA.m'', ''Hbrigeest.mat'', ''Kvw_calc.mat'', ''Hmu_r_erisLargeWheels.mat'', ''LQI_recalc.m'', and ''RADA_ctrlSep.m'' from this directory to you new diectroy as these files will allow you to load the model parameters and controller designs used in Paul Uhing's thesis or find the most recent version of these files an copy them instead. It would also be good to copy and of the ''RADA_psiCtrl_v2.slx'' or ''RADA_psiCtrl_LQGsep.slx'' files here to sever as the base RADA simulation in your new directory. Finally, open te ''DataSets'' directory below the ''RADA'' directory can copy one of the ''RADA_LQG_compPID.mat'' files or ''RADA_LQG_sep.mat'' files because it will allow you to have input vector for the copied ''.slx'' Simulink file.
=== Setting up the MATLAB Workspace ===
Now in MATLAB with you working directory set to you new directory for test RADA simulations run ''modelParams_smallWheels_RADA.m'' from the MATLAB command line ten load the RADA ''.mat'' data file. Now in the Current Folder screen in MATLAB double click on the ''.slx'' and wait for it to open.
=== Settings in Simulink ===
When running a simulation RADA in simulink always make sure your solver is set to '''ode23t'''! The RADA model is a moderately stiff set of differential equations and ode45 the default solver will take an extremely long time to run simulaitons of RADA. You can set the run length to any length you want and then run the simulation.
=== Store Data from Simulink ===
All of the Simulink files in Paul Uhing's Research Repository output simulation data MATLAB structures contain the time and value arrays for important variables. After a simulation finishes these will show up as variables in the MATLAB Workspace. If you want to save any of these values for latter use select them in the MATLAB Workspace and right-click and select save or press ctrl+s to save these variables to a ''.mat'' file.
== Understanding and Modifying RADA Simulations ==
The Simulink models of RADA for Paul Uhing's Thesis is built to be fairly easy to understand. Normal Simulink blocks are used for routing signals and completing simple calculations. For more difficult calculations MATLAB Function blocks are used. These blocks allow you to write MATLAB code to complete some calculation. They can have inputs from the Simulink simulation and parameter inputs from the MATLAB Workspace. This makes complex calculations much easier to understand. The goal of using all of these tricks is to avoid creating a model that is a rat's nest of interconnecting blocks that is impossible trace any errors in the simulation. Understanding how the RADA model was put together wil help you understand how to modify this model and how to build your own models.
=== Components of the Model ===
The model is broken down into subsystems based off of sub-components of the actual system. There is a block for calculating the accelerations of RADA's body, two blocks for calculating the different actuator sets, producing commands to the system, and calculating intermediate values used by other blocks.
==== Body dynamics calculations ====
The body dynamics block (''RADA_BodyDynamcis_v2'') takes in Euler angle position and velocity of the pendulum (including yaw), the global velocity of the ground vehicle, the force produced by the propellers in the x body direction of the pendulum, the force produced by the propellers in the y body direction of the pendulum, and the force produced by each wheel. This block is a MATLAB Function block so it also has parameter inputs. For using MATLAB Function block is is important to never delete:
%#codegen
because this allows the MATLAB code to function in Simulink.
The code inside the block is just the implementation of the final equation in Chapter 3.4 of Paul Uhing's Thesis. The outputs of the block are the acceleration of the pendulum's in pitch and roll, the acceleration of the yaw of the system, and the x and y global acceleration of the ground robot. Then MATLAB continuous time integrator blocks are used to get the corresponding velocities and positions. MATLAB function blocks do not do integration very well so it is easier just to calculate the accelerations and then use the Simulink blocks to integrate.
== Simulink Setup ==
In order to use Simulink effectively you need to setup a few things. Iowa State will allow you download MATLAB and use a site license for free as a student. For more information about installing MATLAB using this site license look [http://it.engineering.iastate.edu/how-to/installing-matlab/ here.] Simulink comes with MATLAB. You should get MATLAB 2014b or latter to ensure the Simulink files from Paul Uhing's research repository will work with your installation of MATLAB.
Once the install is complete and MATLAB is registered you can open MATLAB up. Then change the folder MATLAB will work out of to a directory you will want to work form. It would be best to copy a few files from Paul Uhing's repository to help you get started. Inside of the RADA Research Repository go to ''MATLAB/RADA'' and copy ''modelParams_smallWheels_RADA.m'', ''Hbrigeest.mat'', ''Kvw_calc.mat'', ''Hmu_r_erisLargeWheels.mat'', ''LQI_recalc.m'', and ''RADA_ctrlSep.m'' from this directory to you new diectroy as these files will allow you to load the model parameters and controller designs used in Paul Uhing's thesis or find the most recent version of these files an copy them instead. It would also be good to copy and of the ''RADA_psiCtrl_v2.slx'' or ''RADA_psiCtrl_LQGsep.slx'' files here to sever as the base RADA simulation in your new directory. Finally, open te ''DataSets'' directory below the ''RADA'' directory can copy one of the ''RADA_LQG_compPID.mat'' files or ''RADA_LQG_sep.mat'' files because it will allow you to have input vector for the copied ''.slx'' Simulink file.
=== Setting up the MATLAB Workspace ===
Now in MATLAB with you working directory set to you new directory for test RADA simulations run ''modelParams_smallWheels_RADA.m'' from the MATLAB command line ten load the RADA ''.mat'' data file. Now in the Current Folder screen in MATLAB double click on the ''.slx'' and wait for it to open.
=== Settings in Simulink ===
When running a simulation RADA in simulink always make sure your solver is set to '''ode23t'''! The RADA model is a moderately stiff set of differential equations and ode45 the default solver will take an extremely long time to run simulaitons of RADA. You can set the run length to any length you want and then run the simulation.
=== Store Data from Simulink ===
All of the Simulink files in Paul Uhing's Research Repository output simulation data MATLAB structures contain the time and value arrays for important variables. After a simulation finishes these will show up as variables in the MATLAB Workspace. If you want to save any of these values for latter use select them in the MATLAB Workspace and right-click and select save or press ctrl+s to save these variables to a ''.mat'' file.
== Understanding and Modifying RADA Simulations ==
The Simulink models of RADA for Paul Uhing's Thesis is built to be fairly easy to understand. Normal Simulink blocks are used for routing signals and completing simple calculations. For more difficult calculations MATLAB Function blocks are used. These blocks allow you to write MATLAB code to complete some calculation. They can have inputs from the Simulink simulation and parameter inputs from the MATLAB Workspace. This makes complex calculations much easier to understand. The goal of using all of these tricks is to avoid creating a model that is a rat's nest of interconnecting blocks that is impossible trace any errors in the simulation. Understanding how the RADA model was put together wil help you understand how to modify this model and how to build your own models.
=== Components of the Model ===
The model is broken down into subsystems based off of sub-components of the actual system. There is a block for calculating the accelerations of RADA's body, two blocks for calculating the different actuator sets, producing commands to the system, and calculating intermediate values used by other blocks.
==== Body dynamics calculations ====
The body dynamics block (''RADA_BodyDynamcis_v2'') takes in Euler angle position and velocity of the pendulum (including yaw), the global velocity of the ground vehicle, the force produced by the propellers in the x body direction of the pendulum, the force produced by the propellers in the y body direction of the pendulum, and the force produced by each wheel. This block is a MATLAB Function block so it also has parameter inputs. For using MATLAB Function block is is important to never delete:
%#codegen
because this allows the MATLAB code to function in Simulink.
The code inside the block is just the implementation of the final equation in Chapter 3.4 of Paul Uhing's Thesis. The outputs of the block are the acceleration of the pendulum's in pitch and roll, the acceleration of the yaw of the system, and the x and y global acceleration of the ground robot. Then MATLAB continuous time integrator blocks are used to get the corresponding velocities and positions. MATLAB function blocks do not do integration very well so it is easier just to calculate the accelerations and then use the Simulink blocks to integrate.
==== Actuator dynamics calculations ====
The actuator dynamics in general take in commands from the controller, mix them into individual motor commands and then calculate the force outputs of the motors. There are two actuator dynamics calculation subsystems. One for the propellers and one for the wheels.
===== Propellers =====
The propeller subsystem takes in the the pitch and roll commands, the Euler angle velocities, the cart body velocities and the pitch and roll position. The pitch and roll inputs are mixed into actual motor commands using the ''Pitch_mixer'' and ''Roll_mixer''. These two MATLAB function blocks transform the command into something that can be used by the motor normalized between zero and one. Then the motor command, battery voltage and current motor velocity is passed into the motor MATLAB function blocks. These blocks calculate the acceleration of the propeller motors. That acceleration is integrated and the motor velocity is feedback into the motor block and then sent to the ''motor to force'' block. This MATLAB Function block uses the four propeller velocities, the angular velocities of the pendulum, and the body velocities of the cart. The output of the block is the total force output in the x and y pendulum axis. Finally there is a MATLAB function block, ''localAngleVel'' will calculate convert the global Euler angle velocities to to local body angular velocities. For how the model is generally used this last block isn't necessary but if you are going to have the pendulum do any maneuvers with large angular changes in both pitch and roll using this block will give you better results.
The calculations for all of this blocks come from Chapters 2.2, 3.6 and 3.7 of Paul Uhing's Thesis.
===== Wheels =====
==== System commands ====
==== Body velocity calculations ====
=== Modifying Simulink ===
==== Creating a new simulation ====
==== Modifying existing files ====
==== System commands ====
==== Body velocity calculations ====
=== Modifying Simulink ===
==== Creating a new simulation ====
==== Modifying existing files ====
792b1393ee1bdf03dbde1b54ba9389e1a48f8949
289
288
2016-08-08T17:31:36Z
Pfuhing
5
wikitext
text/x-wiki
== Simulink Setup ==
In order to use Simulink effectively you need to setup a few things. Iowa State will allow you download MATLAB and use a site license for free as a student. For more information about installing MATLAB using this site license look [http://it.engineering.iastate.edu/how-to/installing-matlab/ here.] Simulink comes with MATLAB. You should get MATLAB 2014b or latter to ensure the Simulink files from Paul Uhing's research repository will work with your installation of MATLAB.
Once the install is complete and MATLAB is registered you can open MATLAB up. Then change the folder MATLAB will work out of to a directory you will want to work form. It would be best to copy a few files from Paul Uhing's repository to help you get started. Inside of the RADA Research Repository go to ''MATLAB/RADA'' and copy ''modelParams_smallWheels_RADA.m'', ''Hbrigeest.mat'', ''Kvw_calc.mat'', ''Hmu_r_erisLargeWheels.mat'', ''LQI_recalc.m'', and ''RADA_ctrlSep.m'' from this directory to you new diectroy as these files will allow you to load the model parameters and controller designs used in Paul Uhing's thesis or find the most recent version of these files an copy them instead. It would also be good to copy and of the ''RADA_psiCtrl_v2.slx'' or ''RADA_psiCtrl_LQGsep.slx'' files here to sever as the base RADA simulation in your new directory. Finally, open te ''DataSets'' directory below the ''RADA'' directory can copy one of the ''RADA_LQG_compPID.mat'' files or ''RADA_LQG_sep.mat'' files because it will allow you to have input vector for the copied ''.slx'' Simulink file.
=== Setting up the MATLAB Workspace ===
Now in MATLAB with you working directory set to you new directory for test RADA simulations run ''modelParams_smallWheels_RADA.m'' from the MATLAB command line ten load the RADA ''.mat'' data file. Now in the Current Folder screen in MATLAB double click on the ''.slx'' and wait for it to open.
=== Settings in Simulink ===
When running a simulation RADA in simulink always make sure your solver is set to '''ode23t'''! The RADA model is a moderately stiff set of differential equations and ode45 the default solver will take an extremely long time to run simulaitons of RADA. You can set the run length to any length you want and then run the simulation.
=== Store Data from Simulink ===
All of the Simulink files in Paul Uhing's Research Repository output simulation data MATLAB structures contain the time and value arrays for important variables. After a simulation finishes these will show up as variables in the MATLAB Workspace. If you want to save any of these values for latter use select them in the MATLAB Workspace and right-click and select save or press ctrl+s to save these variables to a ''.mat'' file.
== Understanding and Modifying RADA Simulations ==
The Simulink models of RADA for Paul Uhing's Thesis is built to be fairly easy to understand. Normal Simulink blocks are used for routing signals and completing simple calculations. For more difficult calculations MATLAB Function blocks are used. These blocks allow you to write MATLAB code to complete some calculation. They can have inputs from the Simulink simulation and parameter inputs from the MATLAB Workspace. This makes complex calculations much easier to understand. The goal of using all of these tricks is to avoid creating a model that is a rat's nest of interconnecting blocks that is impossible trace any errors in the simulation. Understanding how the RADA model was put together wil help you understand how to modify this model and how to build your own models.
=== Components of the Model ===
The model is broken down into subsystems based off of sub-components of the actual system. There is a block for calculating the accelerations of RADA's body, two blocks for calculating the different actuator sets, producing commands to the system, and calculating intermediate values used by other blocks.
==== Body dynamics calculations ====
The body dynamics block (''RADA_BodyDynamcis_v2'') takes in Euler angle position and velocity of the pendulum (including yaw), the global velocity of the ground vehicle, the force produced by the propellers in the x body direction of the pendulum, the force produced by the propellers in the y body direction of the pendulum, and the force produced by each wheel. This block is a MATLAB Function block so it also has parameter inputs. For using MATLAB Function block is is important to never delete:
%#codegen
because this allows the MATLAB code to function in Simulink.
The code inside the block is just the implementation of the final equation in Chapter 3.4 of Paul Uhing's Thesis. The outputs of the block are the acceleration of the pendulum's in pitch and roll, the acceleration of the yaw of the system, and the x and y global acceleration of the ground robot. Then MATLAB continuous time integrator blocks are used to get the corresponding velocities and positions. MATLAB function blocks do not do integration very well so it is easier just to calculate the accelerations and then use the Simulink blocks to integrate.
== Simulink Setup ==
In order to use Simulink effectively you need to setup a few things. Iowa State will allow you download MATLAB and use a site license for free as a student. For more information about installing MATLAB using this site license look [http://it.engineering.iastate.edu/how-to/installing-matlab/ here.] Simulink comes with MATLAB. You should get MATLAB 2014b or latter to ensure the Simulink files from Paul Uhing's research repository will work with your installation of MATLAB.
Once the install is complete and MATLAB is registered you can open MATLAB up. Then change the folder MATLAB will work out of to a directory you will want to work form. It would be best to copy a few files from Paul Uhing's repository to help you get started. Inside of the RADA Research Repository go to ''MATLAB/RADA'' and copy ''modelParams_smallWheels_RADA.m'', ''Hbrigeest.mat'', ''Kvw_calc.mat'', ''Hmu_r_erisLargeWheels.mat'', ''LQI_recalc.m'', and ''RADA_ctrlSep.m'' from this directory to you new diectroy as these files will allow you to load the model parameters and controller designs used in Paul Uhing's thesis or find the most recent version of these files an copy them instead. It would also be good to copy and of the ''RADA_psiCtrl_v2.slx'' or ''RADA_psiCtrl_LQGsep.slx'' files here to sever as the base RADA simulation in your new directory. Finally, open te ''DataSets'' directory below the ''RADA'' directory can copy one of the ''RADA_LQG_compPID.mat'' files or ''RADA_LQG_sep.mat'' files because it will allow you to have input vector for the copied ''.slx'' Simulink file.
=== Setting up the MATLAB Workspace ===
Now in MATLAB with you working directory set to you new directory for test RADA simulations run ''modelParams_smallWheels_RADA.m'' from the MATLAB command line ten load the RADA ''.mat'' data file. Now in the Current Folder screen in MATLAB double click on the ''.slx'' and wait for it to open.
=== Settings in Simulink ===
When running a simulation RADA in simulink always make sure your solver is set to '''ode23t'''! The RADA model is a moderately stiff set of differential equations and ode45 the default solver will take an extremely long time to run simulaitons of RADA. You can set the run length to any length you want and then run the simulation.
=== Store Data from Simulink ===
All of the Simulink files in Paul Uhing's Research Repository output simulation data MATLAB structures contain the time and value arrays for important variables. After a simulation finishes these will show up as variables in the MATLAB Workspace. If you want to save any of these values for latter use select them in the MATLAB Workspace and right-click and select save or press ctrl+s to save these variables to a ''.mat'' file.
== Understanding and Modifying RADA Simulations ==
The Simulink models of RADA for Paul Uhing's Thesis is built to be fairly easy to understand. Normal Simulink blocks are used for routing signals and completing simple calculations. For more difficult calculations MATLAB Function blocks are used. These blocks allow you to write MATLAB code to complete some calculation. They can have inputs from the Simulink simulation and parameter inputs from the MATLAB Workspace. This makes complex calculations much easier to understand. The goal of using all of these tricks is to avoid creating a model that is a rat's nest of interconnecting blocks that is impossible trace any errors in the simulation. Understanding how the RADA model was put together wil help you understand how to modify this model and how to build your own models.
=== Components of the Model ===
The model is broken down into subsystems based off of sub-components of the actual system. There is a block for calculating the accelerations of RADA's body, two blocks for calculating the different actuator sets, producing commands to the system, and calculating intermediate values used by other blocks.
==== Body dynamics calculations ====
The body dynamics block (''RADA_BodyDynamcis_v2'') takes in Euler angle position and velocity of the pendulum (including yaw), the global velocity of the ground vehicle, the force produced by the propellers in the x body direction of the pendulum, the force produced by the propellers in the y body direction of the pendulum, and the force produced by each wheel. This block is a MATLAB Function block so it also has parameter inputs. For using MATLAB Function block is is important to never delete:
%#codegen
because this allows the MATLAB code to function in Simulink.
The code inside the block is just the implementation of the final equation in Chapter 3.4 of Paul Uhing's Thesis. The outputs of the block are the acceleration of the pendulum's in pitch and roll, the acceleration of the yaw of the system, and the x and y global acceleration of the ground robot. Then MATLAB continuous time integrator blocks are used to get the corresponding velocities and positions. MATLAB function blocks do not do integration very well so it is easier just to calculate the accelerations and then use the Simulink blocks to integrate.
==== Actuator dynamics calculations ====
The actuator dynamics in general take in commands from the controller, mix them into individual motor commands and then calculate the force outputs of the motors. There are two actuator dynamics calculation subsystems. One for the propellers and one for the wheels.
===== Propellers =====
The propeller subsystem takes in the the pitch and roll commands, the Euler angle velocities, the cart body velocities and the pitch and roll position. The pitch and roll inputs are mixed into actual motor commands using the ''Pitch_mixer'' and ''Roll_mixer''. These two MATLAB function blocks transform the command into something that can be used by the motor normalized between zero and one. Then the motor command, battery voltage and current motor velocity is passed into the motor MATLAB function blocks. These blocks calculate the acceleration of the propeller motors. That acceleration is integrated and the motor velocity is feedback into the motor block and then sent to the ''motor to force'' block. This MATLAB Function block uses the four propeller velocities, the angular velocities of the pendulum, and the body velocities of the cart. The output of the block is the total force output in the x and y pendulum axis. Finally there is a MATLAB function block, ''localAngleVel'' will calculate convert the global Euler angle velocities to to local body angular velocities. For how the model is generally used this last block isn't necessary but if you are going to have the pendulum do any maneuvers with large angular changes in both pitch and roll using this block will give you better results.
The calculations for all of this blocks come from Chapters 2.2, 3.6 and 3.7 of Paul Uhing's Thesis.
===== Wheels =====
==== System commands ====
==== Body velocity calculations ====
=== Modifying Simulink ===
==== Creating a new simulation ====
==== Modifying existing files ====
b25d2df62fd1bbdfd2e7ec69c550888d4e0a41d2
290
289
2016-08-08T17:54:12Z
Pfuhing
5
/* Actuator dynamics calculations */
wikitext
text/x-wiki
== Simulink Setup ==
In order to use Simulink effectively you need to setup a few things. Iowa State will allow you download MATLAB and use a site license for free as a student. For more information about installing MATLAB using this site license look [http://it.engineering.iastate.edu/how-to/installing-matlab/ here.] Simulink comes with MATLAB. You should get MATLAB 2014b or latter to ensure the Simulink files from Paul Uhing's research repository will work with your installation of MATLAB.
Once the install is complete and MATLAB is registered you can open MATLAB up. Then change the folder MATLAB will work out of to a directory you will want to work form. It would be best to copy a few files from Paul Uhing's repository to help you get started. Inside of the RADA Research Repository go to ''MATLAB/RADA'' and copy ''modelParams_smallWheels_RADA.m'', ''Hbrigeest.mat'', ''Kvw_calc.mat'', ''Hmu_r_erisLargeWheels.mat'', ''LQI_recalc.m'', and ''RADA_ctrlSep.m'' from this directory to you new diectroy as these files will allow you to load the model parameters and controller designs used in Paul Uhing's thesis or find the most recent version of these files an copy them instead. It would also be good to copy and of the ''RADA_psiCtrl_v2.slx'' or ''RADA_psiCtrl_LQGsep.slx'' files here to sever as the base RADA simulation in your new directory. Finally, open te ''DataSets'' directory below the ''RADA'' directory can copy one of the ''RADA_LQG_compPID.mat'' files or ''RADA_LQG_sep.mat'' files because it will allow you to have input vector for the copied ''.slx'' Simulink file.
=== Setting up the MATLAB Workspace ===
Now in MATLAB with you working directory set to you new directory for test RADA simulations run ''modelParams_smallWheels_RADA.m'' from the MATLAB command line ten load the RADA ''.mat'' data file. Now in the Current Folder screen in MATLAB double click on the ''.slx'' and wait for it to open.
=== Settings in Simulink ===
When running a simulation RADA in simulink always make sure your solver is set to '''ode23t'''! The RADA model is a moderately stiff set of differential equations and ode45 the default solver will take an extremely long time to run simulaitons of RADA. You can set the run length to any length you want and then run the simulation.
=== Store Data from Simulink ===
All of the Simulink files in Paul Uhing's Research Repository output simulation data MATLAB structures contain the time and value arrays for important variables. After a simulation finishes these will show up as variables in the MATLAB Workspace. If you want to save any of these values for latter use select them in the MATLAB Workspace and right-click and select save or press ctrl+s to save these variables to a ''.mat'' file.
== Understanding and Modifying RADA Simulations ==
The Simulink models of RADA for Paul Uhing's Thesis is built to be fairly easy to understand. Normal Simulink blocks are used for routing signals and completing simple calculations. For more difficult calculations MATLAB Function blocks are used. These blocks allow you to write MATLAB code to complete some calculation. They can have inputs from the Simulink simulation and parameter inputs from the MATLAB Workspace. This makes complex calculations much easier to understand. The goal of using all of these tricks is to avoid creating a model that is a rat's nest of interconnecting blocks that is impossible trace any errors in the simulation. Understanding how the RADA model was put together wil help you understand how to modify this model and how to build your own models.
=== Components of the Model ===
The model is broken down into subsystems based off of sub-components of the actual system. There is a block for calculating the accelerations of RADA's body, two blocks for calculating the different actuator sets, producing commands to the system, and calculating intermediate values used by other blocks.
==== Body dynamics calculations ====
The body dynamics block (''RADA_BodyDynamcis_v2'') takes in Euler angle position and velocity of the pendulum (including yaw), the global velocity of the ground vehicle, the force produced by the propellers in the x body direction of the pendulum, the force produced by the propellers in the y body direction of the pendulum, and the force produced by each wheel. This block is a MATLAB Function block so it also has parameter inputs. For using MATLAB Function block is is important to never delete:
%#codegen
because this allows the MATLAB code to function in Simulink.
The code inside the block is just the implementation of the final equation in Chapter 3.4 of Paul Uhing's Thesis. The outputs of the block are the acceleration of the pendulum's in pitch and roll, the acceleration of the yaw of the system, and the x and y global acceleration of the ground robot. Then MATLAB continuous time integrator blocks are used to get the corresponding velocities and positions. MATLAB function blocks do not do integration very well so it is easier just to calculate the accelerations and then use the Simulink blocks to integrate.
== Simulink Setup ==
In order to use Simulink effectively you need to setup a few things. Iowa State will allow you download MATLAB and use a site license for free as a student. For more information about installing MATLAB using this site license look [http://it.engineering.iastate.edu/how-to/installing-matlab/ here.] Simulink comes with MATLAB. You should get MATLAB 2014b or latter to ensure the Simulink files from Paul Uhing's research repository will work with your installation of MATLAB.
Once the install is complete and MATLAB is registered you can open MATLAB up. Then change the folder MATLAB will work out of to a directory you will want to work form. It would be best to copy a few files from Paul Uhing's repository to help you get started. Inside of the RADA Research Repository go to ''MATLAB/RADA'' and copy ''modelParams_smallWheels_RADA.m'', ''Hbrigeest.mat'', ''Kvw_calc.mat'', ''Hmu_r_erisLargeWheels.mat'', ''LQI_recalc.m'', and ''RADA_ctrlSep.m'' from this directory to you new diectroy as these files will allow you to load the model parameters and controller designs used in Paul Uhing's thesis or find the most recent version of these files an copy them instead. It would also be good to copy and of the ''RADA_psiCtrl_v2.slx'' or ''RADA_psiCtrl_LQGsep.slx'' files here to sever as the base RADA simulation in your new directory. Finally, open te ''DataSets'' directory below the ''RADA'' directory can copy one of the ''RADA_LQG_compPID.mat'' files or ''RADA_LQG_sep.mat'' files because it will allow you to have input vector for the copied ''.slx'' Simulink file.
=== Setting up the MATLAB Workspace ===
Now in MATLAB with you working directory set to you new directory for test RADA simulations run ''modelParams_smallWheels_RADA.m'' from the MATLAB command line ten load the RADA ''.mat'' data file. Now in the Current Folder screen in MATLAB double click on the ''.slx'' and wait for it to open.
=== Settings in Simulink ===
When running a simulation RADA in simulink always make sure your solver is set to '''ode23t'''! The RADA model is a moderately stiff set of differential equations and ode45 the default solver will take an extremely long time to run simulaitons of RADA. You can set the run length to any length you want and then run the simulation.
=== Store Data from Simulink ===
All of the Simulink files in Paul Uhing's Research Repository output simulation data MATLAB structures contain the time and value arrays for important variables. After a simulation finishes these will show up as variables in the MATLAB Workspace. If you want to save any of these values for latter use select them in the MATLAB Workspace and right-click and select save or press ctrl+s to save these variables to a ''.mat'' file.
== Understanding and Modifying RADA Simulations ==
The Simulink models of RADA for Paul Uhing's Thesis is built to be fairly easy to understand. Normal Simulink blocks are used for routing signals and completing simple calculations. For more difficult calculations MATLAB Function blocks are used. These blocks allow you to write MATLAB code to complete some calculation. They can have inputs from the Simulink simulation and parameter inputs from the MATLAB Workspace. This makes complex calculations much easier to understand. The goal of using all of these tricks is to avoid creating a model that is a rat's nest of interconnecting blocks that is impossible trace any errors in the simulation. Understanding how the RADA model was put together wil help you understand how to modify this model and how to build your own models.
=== Components of the Model ===
The model is broken down into subsystems based off of sub-components of the actual system. There is a block for calculating the accelerations of RADA's body, two blocks for calculating the different actuator sets, producing commands to the system, and calculating intermediate values used by other blocks.
==== Body dynamics calculations ====
The body dynamics block (''RADA_BodyDynamcis_v2'') takes in Euler angle position and velocity of the pendulum (including yaw), the global velocity of the ground vehicle, the force produced by the propellers in the x body direction of the pendulum, the force produced by the propellers in the y body direction of the pendulum, and the force produced by each wheel. This block is a MATLAB Function block so it also has parameter inputs. For using MATLAB Function block is is important to never delete:
%#codegen
because this allows the MATLAB code to function in Simulink.
The code inside the block is just the implementation of the final equation in Chapter 3.4 of Paul Uhing's Thesis. The outputs of the block are the acceleration of the pendulum's in pitch and roll, the acceleration of the yaw of the system, and the x and y global acceleration of the ground robot. Then MATLAB continuous time integrator blocks are used to get the corresponding velocities and positions. MATLAB function blocks do not do integration very well so it is easier just to calculate the accelerations and then use the Simulink blocks to integrate.
==== Actuator dynamics calculations ====
The actuator dynamics in general take in commands from the controller, mix them into individual motor commands and then calculate the force outputs of the motors. There are two actuator dynamics calculation subsystems. One for the propellers and one for the wheels. The controller output is calculated before these blocks and after the input command block. You just put whatever controller you want to use.
===== Propellers =====
The propeller subsystem takes in the the pitch and roll commands, the Euler angle velocities, the cart body velocities and the pitch and roll position. The pitch and roll inputs are mixed into actual motor commands using the ''Pitch_mixer'' and ''Roll_mixer''. These two MATLAB function blocks transform the command into something that can be used by the motor normalized between zero and one. Then the motor command, battery voltage and current motor velocity is passed into the motor MATLAB function blocks. These blocks calculate the acceleration of the propeller motors. That acceleration is integrated and the motor velocity is feedback into the motor block and then sent to the ''motor to force'' block. This MATLAB Function block uses the four propeller velocities, the angular velocities of the pendulum, and the body velocities of the cart. The output of the block is the total force output in the x and y pendulum axis. Finally there is a MATLAB function block, ''localAngleVel'' will calculate convert the global Euler angle velocities to to local body angular velocities. For how the model is generally used this last block isn't necessary but if you are going to have the pendulum do any maneuvers with large angular changes in both pitch and roll using this block will give you better results.
The calculations for all of this blocks come from Chapters 2.2, 3.6 and 3.7 of Paul Uhing's Thesis.
===== Wheels =====
The ''WheelForce'' subsystem of the RADA model takes in the heading, x and y controller outputs, the body linear velocities of the cart, the yaw velocity of the cart, the heading of the cart and finally takes in the x and y reference commands. This block then outputs the force produced by each of the four wheels.
The heading controller output command, the x and y velocity commands, the heading of the robot, and finally the x and y reference velocities are put into the wheel command mixing matrix, ''Wheel input mixer''. If you are using PIDs you will want to force this heading input to be zero all the time. This block calculate the command that should be sent to each wheel. These wheel commands pass though some saturation and scaling blocks and then are passed into the ''H-bridge model'' MATLAB Function block. This converts the controller output to a command for the motor between -1 and 1. This command is passed into the ''motor'' subsystems. These blocks take in this command the battery voltage and the velocity of the wheel which was summed from the body linear velocities of the cart and yaw velocity. This subsystem uses Simulink blocks to calculate the force produced by each wheel. The calcaultions done in this subsystem can be found in Chapters 3.5 and 3.7 of Paul Uhing's Thesis.
==== System commands ====
==== Body velocity calculations ====
=== Modifying Simulink ===
==== Creating a new simulation ====
==== Modifying existing files ====
23475f093d27abc3d1ea2f0b9f1671959766e093
291
290
2016-08-08T17:54:41Z
Pfuhing
5
/* Body dynamics calculations */
wikitext
text/x-wiki
== Simulink Setup ==
In order to use Simulink effectively you need to setup a few things. Iowa State will allow you download MATLAB and use a site license for free as a student. For more information about installing MATLAB using this site license look [http://it.engineering.iastate.edu/how-to/installing-matlab/ here.] Simulink comes with MATLAB. You should get MATLAB 2014b or latter to ensure the Simulink files from Paul Uhing's research repository will work with your installation of MATLAB.
Once the install is complete and MATLAB is registered you can open MATLAB up. Then change the folder MATLAB will work out of to a directory you will want to work form. It would be best to copy a few files from Paul Uhing's repository to help you get started. Inside of the RADA Research Repository go to ''MATLAB/RADA'' and copy ''modelParams_smallWheels_RADA.m'', ''Hbrigeest.mat'', ''Kvw_calc.mat'', ''Hmu_r_erisLargeWheels.mat'', ''LQI_recalc.m'', and ''RADA_ctrlSep.m'' from this directory to you new diectroy as these files will allow you to load the model parameters and controller designs used in Paul Uhing's thesis or find the most recent version of these files an copy them instead. It would also be good to copy and of the ''RADA_psiCtrl_v2.slx'' or ''RADA_psiCtrl_LQGsep.slx'' files here to sever as the base RADA simulation in your new directory. Finally, open te ''DataSets'' directory below the ''RADA'' directory can copy one of the ''RADA_LQG_compPID.mat'' files or ''RADA_LQG_sep.mat'' files because it will allow you to have input vector for the copied ''.slx'' Simulink file.
=== Setting up the MATLAB Workspace ===
Now in MATLAB with you working directory set to you new directory for test RADA simulations run ''modelParams_smallWheels_RADA.m'' from the MATLAB command line ten load the RADA ''.mat'' data file. Now in the Current Folder screen in MATLAB double click on the ''.slx'' and wait for it to open.
=== Settings in Simulink ===
When running a simulation RADA in simulink always make sure your solver is set to '''ode23t'''! The RADA model is a moderately stiff set of differential equations and ode45 the default solver will take an extremely long time to run simulaitons of RADA. You can set the run length to any length you want and then run the simulation.
=== Store Data from Simulink ===
All of the Simulink files in Paul Uhing's Research Repository output simulation data MATLAB structures contain the time and value arrays for important variables. After a simulation finishes these will show up as variables in the MATLAB Workspace. If you want to save any of these values for latter use select them in the MATLAB Workspace and right-click and select save or press ctrl+s to save these variables to a ''.mat'' file.
== Understanding and Modifying RADA Simulations ==
The Simulink models of RADA for Paul Uhing's Thesis is built to be fairly easy to understand. Normal Simulink blocks are used for routing signals and completing simple calculations. For more difficult calculations MATLAB Function blocks are used. These blocks allow you to write MATLAB code to complete some calculation. They can have inputs from the Simulink simulation and parameter inputs from the MATLAB Workspace. This makes complex calculations much easier to understand. The goal of using all of these tricks is to avoid creating a model that is a rat's nest of interconnecting blocks that is impossible trace any errors in the simulation. Understanding how the RADA model was put together wil help you understand how to modify this model and how to build your own models.
=== Components of the Model ===
The model is broken down into subsystems based off of sub-components of the actual system. There is a block for calculating the accelerations of RADA's body, two blocks for calculating the different actuator sets, producing commands to the system, and calculating intermediate values used by other blocks.
==== Body dynamics calculations ====
The body dynamics block (''RADA_BodyDynamcis_v2'') takes in Euler angle position and velocity of the pendulum (including yaw), the global velocity of the ground vehicle, the force produced by the propellers in the x body direction of the pendulum, the force produced by the propellers in the y body direction of the pendulum, and the force produced by each wheel. This block is a MATLAB Function block so it also has parameter inputs. For using MATLAB Function block is is important to never delete:
%#codegen
because this allows the MATLAB code to function in Simulink.
The code inside the block is just the implementation of the final equation in Chapter 3.4 of Paul Uhing's Thesis. The outputs of the block are the acceleration of the pendulum's in pitch and roll, the acceleration of the yaw of the system, and the x and y global acceleration of the ground robot. Then MATLAB continuous time integrator blocks are used to get the corresponding velocities and positions. MATLAB function blocks do not do integration very well so it is easier just to calculate the accelerations and then use the Simulink blocks to integrate.
== Simulink Setup ==
In order to use Simulink effectively you need to setup a few things. Iowa State will allow you download MATLAB and use a site license for free as a student. For more information about installing MATLAB using this site license look [http://it.engineering.iastate.edu/how-to/installing-matlab/ here.] Simulink comes with MATLAB. You should get MATLAB 2014b or latter to ensure the Simulink files from Paul Uhing's research repository will work with your installation of MATLAB.
Once the install is complete and MATLAB is registered you can open MATLAB up. Then change the folder MATLAB will work out of to a directory you will want to work form. It would be best to copy a few files from Paul Uhing's repository to help you get started. Inside of the RADA Research Repository go to ''MATLAB/RADA'' and copy ''modelParams_smallWheels_RADA.m'', ''Hbrigeest.mat'', ''Kvw_calc.mat'', ''Hmu_r_erisLargeWheels.mat'', ''LQI_recalc.m'', and ''RADA_ctrlSep.m'' from this directory to you new diectroy as these files will allow you to load the model parameters and controller designs used in Paul Uhing's thesis or find the most recent version of these files an copy them instead. It would also be good to copy and of the ''RADA_psiCtrl_v2.slx'' or ''RADA_psiCtrl_LQGsep.slx'' files here to sever as the base RADA simulation in your new directory. Finally, open te ''DataSets'' directory below the ''RADA'' directory can copy one of the ''RADA_LQG_compPID.mat'' files or ''RADA_LQG_sep.mat'' files because it will allow you to have input vector for the copied ''.slx'' Simulink file.
=== Setting up the MATLAB Workspace ===
Now in MATLAB with you working directory set to you new directory for test RADA simulations run ''modelParams_smallWheels_RADA.m'' from the MATLAB command line ten load the RADA ''.mat'' data file. Now in the Current Folder screen in MATLAB double click on the ''.slx'' and wait for it to open.
=== Settings in Simulink ===
When running a simulation RADA in simulink always make sure your solver is set to '''ode23t'''! The RADA model is a moderately stiff set of differential equations and ode45 the default solver will take an extremely long time to run simulaitons of RADA. You can set the run length to any length you want and then run the simulation.
=== Store Data from Simulink ===
All of the Simulink files in Paul Uhing's Research Repository output simulation data MATLAB structures contain the time and value arrays for important variables. After a simulation finishes these will show up as variables in the MATLAB Workspace. If you want to save any of these values for latter use select them in the MATLAB Workspace and right-click and select save or press ctrl+s to save these variables to a ''.mat'' file.
== Understanding and Modifying RADA Simulations ==
The Simulink models of RADA for Paul Uhing's Thesis is built to be fairly easy to understand. Normal Simulink blocks are used for routing signals and completing simple calculations. For more difficult calculations MATLAB Function blocks are used. These blocks allow you to write MATLAB code to complete some calculation. They can have inputs from the Simulink simulation and parameter inputs from the MATLAB Workspace. This makes complex calculations much easier to understand. The goal of using all of these tricks is to avoid creating a model that is a rat's nest of interconnecting blocks that is impossible trace any errors in the simulation. Understanding how the RADA model was put together wil help you understand how to modify this model and how to build your own models.
=== Components of the Model ===
The model is broken down into subsystems based off of sub-components of the actual system. There is a block for calculating the accelerations of RADA's body, two blocks for calculating the different actuator sets, producing commands to the system, and calculating intermediate values used by other blocks.
==== Body dynamics calculations ====
The body dynamics block (''RADA_BodyDynamcis_v2'') takes in Euler angle position and velocity of the pendulum (including yaw), the global velocity of the ground vehicle, the force produced by the propellers in the x body direction of the pendulum, the force produced by the propellers in the y body direction of the pendulum, and the force produced by each wheel. This block is a MATLAB Function block so it also has parameter inputs. For using MATLAB Function block is is important to never delete:
%#codegen
because this allows the MATLAB code to function in Simulink.
The code inside the block is just the implementation of the final equation in Chapter 3.4 and 3.5 of Paul Uhing's Thesis. The outputs of the block are the acceleration of the pendulum's in pitch and roll, the acceleration of the yaw of the system, and the x and y global acceleration of the ground robot. Then MATLAB continuous time integrator blocks are used to get the corresponding velocities and positions. MATLAB function blocks do not do integration very well so it is easier just to calculate the accelerations and then use the Simulink blocks to integrate.
==== Actuator dynamics calculations ====
The actuator dynamics in general take in commands from the controller, mix them into individual motor commands and then calculate the force outputs of the motors. There are two actuator dynamics calculation subsystems. One for the propellers and one for the wheels. The controller output is calculated before these blocks and after the input command block. You just put whatever controller you want to use.
===== Propellers =====
The propeller subsystem takes in the the pitch and roll commands, the Euler angle velocities, the cart body velocities and the pitch and roll position. The pitch and roll inputs are mixed into actual motor commands using the ''Pitch_mixer'' and ''Roll_mixer''. These two MATLAB function blocks transform the command into something that can be used by the motor normalized between zero and one. Then the motor command, battery voltage and current motor velocity is passed into the motor MATLAB function blocks. These blocks calculate the acceleration of the propeller motors. That acceleration is integrated and the motor velocity is feedback into the motor block and then sent to the ''motor to force'' block. This MATLAB Function block uses the four propeller velocities, the angular velocities of the pendulum, and the body velocities of the cart. The output of the block is the total force output in the x and y pendulum axis. Finally there is a MATLAB function block, ''localAngleVel'' will calculate convert the global Euler angle velocities to to local body angular velocities. For how the model is generally used this last block isn't necessary but if you are going to have the pendulum do any maneuvers with large angular changes in both pitch and roll using this block will give you better results.
The calculations for all of this blocks come from Chapters 2.2, 3.6 and 3.7 of Paul Uhing's Thesis.
===== Wheels =====
The ''WheelForce'' subsystem of the RADA model takes in the heading, x and y controller outputs, the body linear velocities of the cart, the yaw velocity of the cart, the heading of the cart and finally takes in the x and y reference commands. This block then outputs the force produced by each of the four wheels.
The heading controller output command, the x and y velocity commands, the heading of the robot, and finally the x and y reference velocities are put into the wheel command mixing matrix, ''Wheel input mixer''. If you are using PIDs you will want to force this heading input to be zero all the time. This block calculate the command that should be sent to each wheel. These wheel commands pass though some saturation and scaling blocks and then are passed into the ''H-bridge model'' MATLAB Function block. This converts the controller output to a command for the motor between -1 and 1. This command is passed into the ''motor'' subsystems. These blocks take in this command the battery voltage and the velocity of the wheel which was summed from the body linear velocities of the cart and yaw velocity. This subsystem uses Simulink blocks to calculate the force produced by each wheel. The calcaultions done in this subsystem can be found in Chapters 3.5 and 3.7 of Paul Uhing's Thesis.
==== System commands ====
==== Body velocity calculations ====
=== Modifying Simulink ===
==== Creating a new simulation ====
==== Modifying existing files ====
560b2760b721bb9f5f01467eda04171fcd2bfd7c
292
291
2016-08-08T17:56:47Z
Pfuhing
5
/* System commands */
wikitext
text/x-wiki
== Simulink Setup ==
In order to use Simulink effectively you need to setup a few things. Iowa State will allow you download MATLAB and use a site license for free as a student. For more information about installing MATLAB using this site license look [http://it.engineering.iastate.edu/how-to/installing-matlab/ here.] Simulink comes with MATLAB. You should get MATLAB 2014b or latter to ensure the Simulink files from Paul Uhing's research repository will work with your installation of MATLAB.
Once the install is complete and MATLAB is registered you can open MATLAB up. Then change the folder MATLAB will work out of to a directory you will want to work form. It would be best to copy a few files from Paul Uhing's repository to help you get started. Inside of the RADA Research Repository go to ''MATLAB/RADA'' and copy ''modelParams_smallWheels_RADA.m'', ''Hbrigeest.mat'', ''Kvw_calc.mat'', ''Hmu_r_erisLargeWheels.mat'', ''LQI_recalc.m'', and ''RADA_ctrlSep.m'' from this directory to you new diectroy as these files will allow you to load the model parameters and controller designs used in Paul Uhing's thesis or find the most recent version of these files an copy them instead. It would also be good to copy and of the ''RADA_psiCtrl_v2.slx'' or ''RADA_psiCtrl_LQGsep.slx'' files here to sever as the base RADA simulation in your new directory. Finally, open te ''DataSets'' directory below the ''RADA'' directory can copy one of the ''RADA_LQG_compPID.mat'' files or ''RADA_LQG_sep.mat'' files because it will allow you to have input vector for the copied ''.slx'' Simulink file.
=== Setting up the MATLAB Workspace ===
Now in MATLAB with you working directory set to you new directory for test RADA simulations run ''modelParams_smallWheels_RADA.m'' from the MATLAB command line ten load the RADA ''.mat'' data file. Now in the Current Folder screen in MATLAB double click on the ''.slx'' and wait for it to open.
=== Settings in Simulink ===
When running a simulation RADA in simulink always make sure your solver is set to '''ode23t'''! The RADA model is a moderately stiff set of differential equations and ode45 the default solver will take an extremely long time to run simulaitons of RADA. You can set the run length to any length you want and then run the simulation.
=== Store Data from Simulink ===
All of the Simulink files in Paul Uhing's Research Repository output simulation data MATLAB structures contain the time and value arrays for important variables. After a simulation finishes these will show up as variables in the MATLAB Workspace. If you want to save any of these values for latter use select them in the MATLAB Workspace and right-click and select save or press ctrl+s to save these variables to a ''.mat'' file.
== Understanding and Modifying RADA Simulations ==
The Simulink models of RADA for Paul Uhing's Thesis is built to be fairly easy to understand. Normal Simulink blocks are used for routing signals and completing simple calculations. For more difficult calculations MATLAB Function blocks are used. These blocks allow you to write MATLAB code to complete some calculation. They can have inputs from the Simulink simulation and parameter inputs from the MATLAB Workspace. This makes complex calculations much easier to understand. The goal of using all of these tricks is to avoid creating a model that is a rat's nest of interconnecting blocks that is impossible trace any errors in the simulation. Understanding how the RADA model was put together wil help you understand how to modify this model and how to build your own models.
=== Components of the Model ===
The model is broken down into subsystems based off of sub-components of the actual system. There is a block for calculating the accelerations of RADA's body, two blocks for calculating the different actuator sets, producing commands to the system, and calculating intermediate values used by other blocks.
==== Body dynamics calculations ====
The body dynamics block (''RADA_BodyDynamcis_v2'') takes in Euler angle position and velocity of the pendulum (including yaw), the global velocity of the ground vehicle, the force produced by the propellers in the x body direction of the pendulum, the force produced by the propellers in the y body direction of the pendulum, and the force produced by each wheel. This block is a MATLAB Function block so it also has parameter inputs. For using MATLAB Function block is is important to never delete:
%#codegen
because this allows the MATLAB code to function in Simulink.
The code inside the block is just the implementation of the final equation in Chapter 3.4 of Paul Uhing's Thesis. The outputs of the block are the acceleration of the pendulum's in pitch and roll, the acceleration of the yaw of the system, and the x and y global acceleration of the ground robot. Then MATLAB continuous time integrator blocks are used to get the corresponding velocities and positions. MATLAB function blocks do not do integration very well so it is easier just to calculate the accelerations and then use the Simulink blocks to integrate.
== Simulink Setup ==
In order to use Simulink effectively you need to setup a few things. Iowa State will allow you download MATLAB and use a site license for free as a student. For more information about installing MATLAB using this site license look [http://it.engineering.iastate.edu/how-to/installing-matlab/ here.] Simulink comes with MATLAB. You should get MATLAB 2014b or latter to ensure the Simulink files from Paul Uhing's research repository will work with your installation of MATLAB.
Once the install is complete and MATLAB is registered you can open MATLAB up. Then change the folder MATLAB will work out of to a directory you will want to work form. It would be best to copy a few files from Paul Uhing's repository to help you get started. Inside of the RADA Research Repository go to ''MATLAB/RADA'' and copy ''modelParams_smallWheels_RADA.m'', ''Hbrigeest.mat'', ''Kvw_calc.mat'', ''Hmu_r_erisLargeWheels.mat'', ''LQI_recalc.m'', and ''RADA_ctrlSep.m'' from this directory to you new diectroy as these files will allow you to load the model parameters and controller designs used in Paul Uhing's thesis or find the most recent version of these files an copy them instead. It would also be good to copy and of the ''RADA_psiCtrl_v2.slx'' or ''RADA_psiCtrl_LQGsep.slx'' files here to sever as the base RADA simulation in your new directory. Finally, open te ''DataSets'' directory below the ''RADA'' directory can copy one of the ''RADA_LQG_compPID.mat'' files or ''RADA_LQG_sep.mat'' files because it will allow you to have input vector for the copied ''.slx'' Simulink file.
=== Setting up the MATLAB Workspace ===
Now in MATLAB with you working directory set to you new directory for test RADA simulations run ''modelParams_smallWheels_RADA.m'' from the MATLAB command line ten load the RADA ''.mat'' data file. Now in the Current Folder screen in MATLAB double click on the ''.slx'' and wait for it to open.
=== Settings in Simulink ===
When running a simulation RADA in simulink always make sure your solver is set to '''ode23t'''! The RADA model is a moderately stiff set of differential equations and ode45 the default solver will take an extremely long time to run simulaitons of RADA. You can set the run length to any length you want and then run the simulation.
=== Store Data from Simulink ===
All of the Simulink files in Paul Uhing's Research Repository output simulation data MATLAB structures contain the time and value arrays for important variables. After a simulation finishes these will show up as variables in the MATLAB Workspace. If you want to save any of these values for latter use select them in the MATLAB Workspace and right-click and select save or press ctrl+s to save these variables to a ''.mat'' file.
== Understanding and Modifying RADA Simulations ==
The Simulink models of RADA for Paul Uhing's Thesis is built to be fairly easy to understand. Normal Simulink blocks are used for routing signals and completing simple calculations. For more difficult calculations MATLAB Function blocks are used. These blocks allow you to write MATLAB code to complete some calculation. They can have inputs from the Simulink simulation and parameter inputs from the MATLAB Workspace. This makes complex calculations much easier to understand. The goal of using all of these tricks is to avoid creating a model that is a rat's nest of interconnecting blocks that is impossible trace any errors in the simulation. Understanding how the RADA model was put together wil help you understand how to modify this model and how to build your own models.
=== Components of the Model ===
The model is broken down into subsystems based off of sub-components of the actual system. There is a block for calculating the accelerations of RADA's body, two blocks for calculating the different actuator sets, producing commands to the system, and calculating intermediate values used by other blocks.
==== Body dynamics calculations ====
The body dynamics block (''RADA_BodyDynamcis_v2'') takes in Euler angle position and velocity of the pendulum (including yaw), the global velocity of the ground vehicle, the force produced by the propellers in the x body direction of the pendulum, the force produced by the propellers in the y body direction of the pendulum, and the force produced by each wheel. This block is a MATLAB Function block so it also has parameter inputs. For using MATLAB Function block is is important to never delete:
%#codegen
because this allows the MATLAB code to function in Simulink.
The code inside the block is just the implementation of the final equation in Chapter 3.4 and 3.5 of Paul Uhing's Thesis. The outputs of the block are the acceleration of the pendulum's in pitch and roll, the acceleration of the yaw of the system, and the x and y global acceleration of the ground robot. Then MATLAB continuous time integrator blocks are used to get the corresponding velocities and positions. MATLAB function blocks do not do integration very well so it is easier just to calculate the accelerations and then use the Simulink blocks to integrate.
==== Actuator dynamics calculations ====
The actuator dynamics in general take in commands from the controller, mix them into individual motor commands and then calculate the force outputs of the motors. There are two actuator dynamics calculation subsystems. One for the propellers and one for the wheels. The controller output is calculated before these blocks and after the input command block. You just put whatever controller you want to use.
===== Propellers =====
The propeller subsystem takes in the the pitch and roll commands, the Euler angle velocities, the cart body velocities and the pitch and roll position. The pitch and roll inputs are mixed into actual motor commands using the ''Pitch_mixer'' and ''Roll_mixer''. These two MATLAB function blocks transform the command into something that can be used by the motor normalized between zero and one. Then the motor command, battery voltage and current motor velocity is passed into the motor MATLAB function blocks. These blocks calculate the acceleration of the propeller motors. That acceleration is integrated and the motor velocity is feedback into the motor block and then sent to the ''motor to force'' block. This MATLAB Function block uses the four propeller velocities, the angular velocities of the pendulum, and the body velocities of the cart. The output of the block is the total force output in the x and y pendulum axis. Finally there is a MATLAB function block, ''localAngleVel'' will calculate convert the global Euler angle velocities to to local body angular velocities. For how the model is generally used this last block isn't necessary but if you are going to have the pendulum do any maneuvers with large angular changes in both pitch and roll using this block will give you better results.
The calculations for all of this blocks come from Chapters 2.2, 3.6 and 3.7 of Paul Uhing's Thesis.
===== Wheels =====
The ''WheelForce'' subsystem of the RADA model takes in the heading, x and y controller outputs, the body linear velocities of the cart, the yaw velocity of the cart, the heading of the cart and finally takes in the x and y reference commands. This block then outputs the force produced by each of the four wheels.
The heading controller output command, the x and y velocity commands, the heading of the robot, and finally the x and y reference velocities are put into the wheel command mixing matrix, ''Wheel input mixer''. If you are using PIDs you will want to force this heading input to be zero all the time. This block calculate the command that should be sent to each wheel. These wheel commands pass though some saturation and scaling blocks and then are passed into the ''H-bridge model'' MATLAB Function block. This converts the controller output to a command for the motor between -1 and 1. This command is passed into the ''motor'' subsystems. These blocks take in this command the battery voltage and the velocity of the wheel which was summed from the body linear velocities of the cart and yaw velocity. This subsystem uses Simulink blocks to calculate the force produced by each wheel. The calcaultions done in this subsystem can be found in Chapters 3.5 and 3.7 of Paul Uhing's Thesis.
==== System commands ====
The system commands block is fairly strait forward. This subsystem just uses the From_Workspace Simulink blocks, step inputs and other Simulink source blocks to create the input reference commands for the simulation.
==== Body velocity calculations ====
=== Modifying Simulink ===
==== Creating a new simulation ====
==== Modifying existing files ====
760d430a5661e447af900988969a299aff23d394
293
292
2016-08-08T17:59:05Z
Pfuhing
5
/* Body velocity calculations */
wikitext
text/x-wiki
== Simulink Setup ==
In order to use Simulink effectively you need to setup a few things. Iowa State will allow you download MATLAB and use a site license for free as a student. For more information about installing MATLAB using this site license look [http://it.engineering.iastate.edu/how-to/installing-matlab/ here.] Simulink comes with MATLAB. You should get MATLAB 2014b or latter to ensure the Simulink files from Paul Uhing's research repository will work with your installation of MATLAB.
Once the install is complete and MATLAB is registered you can open MATLAB up. Then change the folder MATLAB will work out of to a directory you will want to work form. It would be best to copy a few files from Paul Uhing's repository to help you get started. Inside of the RADA Research Repository go to ''MATLAB/RADA'' and copy ''modelParams_smallWheels_RADA.m'', ''Hbrigeest.mat'', ''Kvw_calc.mat'', ''Hmu_r_erisLargeWheels.mat'', ''LQI_recalc.m'', and ''RADA_ctrlSep.m'' from this directory to you new diectroy as these files will allow you to load the model parameters and controller designs used in Paul Uhing's thesis or find the most recent version of these files an copy them instead. It would also be good to copy and of the ''RADA_psiCtrl_v2.slx'' or ''RADA_psiCtrl_LQGsep.slx'' files here to sever as the base RADA simulation in your new directory. Finally, open te ''DataSets'' directory below the ''RADA'' directory can copy one of the ''RADA_LQG_compPID.mat'' files or ''RADA_LQG_sep.mat'' files because it will allow you to have input vector for the copied ''.slx'' Simulink file.
=== Setting up the MATLAB Workspace ===
Now in MATLAB with you working directory set to you new directory for test RADA simulations run ''modelParams_smallWheels_RADA.m'' from the MATLAB command line ten load the RADA ''.mat'' data file. Now in the Current Folder screen in MATLAB double click on the ''.slx'' and wait for it to open.
=== Settings in Simulink ===
When running a simulation RADA in simulink always make sure your solver is set to '''ode23t'''! The RADA model is a moderately stiff set of differential equations and ode45 the default solver will take an extremely long time to run simulaitons of RADA. You can set the run length to any length you want and then run the simulation.
=== Store Data from Simulink ===
All of the Simulink files in Paul Uhing's Research Repository output simulation data MATLAB structures contain the time and value arrays for important variables. After a simulation finishes these will show up as variables in the MATLAB Workspace. If you want to save any of these values for latter use select them in the MATLAB Workspace and right-click and select save or press ctrl+s to save these variables to a ''.mat'' file.
== Understanding and Modifying RADA Simulations ==
The Simulink models of RADA for Paul Uhing's Thesis is built to be fairly easy to understand. Normal Simulink blocks are used for routing signals and completing simple calculations. For more difficult calculations MATLAB Function blocks are used. These blocks allow you to write MATLAB code to complete some calculation. They can have inputs from the Simulink simulation and parameter inputs from the MATLAB Workspace. This makes complex calculations much easier to understand. The goal of using all of these tricks is to avoid creating a model that is a rat's nest of interconnecting blocks that is impossible trace any errors in the simulation. Understanding how the RADA model was put together wil help you understand how to modify this model and how to build your own models.
=== Components of the Model ===
The model is broken down into subsystems based off of sub-components of the actual system. There is a block for calculating the accelerations of RADA's body, two blocks for calculating the different actuator sets, producing commands to the system, and calculating intermediate values used by other blocks.
==== Body dynamics calculations ====
The body dynamics block (''RADA_BodyDynamcis_v2'') takes in Euler angle position and velocity of the pendulum (including yaw), the global velocity of the ground vehicle, the force produced by the propellers in the x body direction of the pendulum, the force produced by the propellers in the y body direction of the pendulum, and the force produced by each wheel. This block is a MATLAB Function block so it also has parameter inputs. For using MATLAB Function block is is important to never delete:
%#codegen
because this allows the MATLAB code to function in Simulink.
The code inside the block is just the implementation of the final equation in Chapter 3.4 of Paul Uhing's Thesis. The outputs of the block are the acceleration of the pendulum's in pitch and roll, the acceleration of the yaw of the system, and the x and y global acceleration of the ground robot. Then MATLAB continuous time integrator blocks are used to get the corresponding velocities and positions. MATLAB function blocks do not do integration very well so it is easier just to calculate the accelerations and then use the Simulink blocks to integrate.
== Simulink Setup ==
In order to use Simulink effectively you need to setup a few things. Iowa State will allow you download MATLAB and use a site license for free as a student. For more information about installing MATLAB using this site license look [http://it.engineering.iastate.edu/how-to/installing-matlab/ here.] Simulink comes with MATLAB. You should get MATLAB 2014b or latter to ensure the Simulink files from Paul Uhing's research repository will work with your installation of MATLAB.
Once the install is complete and MATLAB is registered you can open MATLAB up. Then change the folder MATLAB will work out of to a directory you will want to work form. It would be best to copy a few files from Paul Uhing's repository to help you get started. Inside of the RADA Research Repository go to ''MATLAB/RADA'' and copy ''modelParams_smallWheels_RADA.m'', ''Hbrigeest.mat'', ''Kvw_calc.mat'', ''Hmu_r_erisLargeWheels.mat'', ''LQI_recalc.m'', and ''RADA_ctrlSep.m'' from this directory to you new diectroy as these files will allow you to load the model parameters and controller designs used in Paul Uhing's thesis or find the most recent version of these files an copy them instead. It would also be good to copy and of the ''RADA_psiCtrl_v2.slx'' or ''RADA_psiCtrl_LQGsep.slx'' files here to sever as the base RADA simulation in your new directory. Finally, open te ''DataSets'' directory below the ''RADA'' directory can copy one of the ''RADA_LQG_compPID.mat'' files or ''RADA_LQG_sep.mat'' files because it will allow you to have input vector for the copied ''.slx'' Simulink file.
=== Setting up the MATLAB Workspace ===
Now in MATLAB with you working directory set to you new directory for test RADA simulations run ''modelParams_smallWheels_RADA.m'' from the MATLAB command line ten load the RADA ''.mat'' data file. Now in the Current Folder screen in MATLAB double click on the ''.slx'' and wait for it to open.
=== Settings in Simulink ===
When running a simulation RADA in simulink always make sure your solver is set to '''ode23t'''! The RADA model is a moderately stiff set of differential equations and ode45 the default solver will take an extremely long time to run simulaitons of RADA. You can set the run length to any length you want and then run the simulation.
=== Store Data from Simulink ===
All of the Simulink files in Paul Uhing's Research Repository output simulation data MATLAB structures contain the time and value arrays for important variables. After a simulation finishes these will show up as variables in the MATLAB Workspace. If you want to save any of these values for latter use select them in the MATLAB Workspace and right-click and select save or press ctrl+s to save these variables to a ''.mat'' file.
== Understanding and Modifying RADA Simulations ==
The Simulink models of RADA for Paul Uhing's Thesis is built to be fairly easy to understand. Normal Simulink blocks are used for routing signals and completing simple calculations. For more difficult calculations MATLAB Function blocks are used. These blocks allow you to write MATLAB code to complete some calculation. They can have inputs from the Simulink simulation and parameter inputs from the MATLAB Workspace. This makes complex calculations much easier to understand. The goal of using all of these tricks is to avoid creating a model that is a rat's nest of interconnecting blocks that is impossible trace any errors in the simulation. Understanding how the RADA model was put together wil help you understand how to modify this model and how to build your own models.
=== Components of the Model ===
The model is broken down into subsystems based off of sub-components of the actual system. There is a block for calculating the accelerations of RADA's body, two blocks for calculating the different actuator sets, producing commands to the system, and calculating intermediate values used by other blocks.
==== Body dynamics calculations ====
The body dynamics block (''RADA_BodyDynamcis_v2'') takes in Euler angle position and velocity of the pendulum (including yaw), the global velocity of the ground vehicle, the force produced by the propellers in the x body direction of the pendulum, the force produced by the propellers in the y body direction of the pendulum, and the force produced by each wheel. This block is a MATLAB Function block so it also has parameter inputs. For using MATLAB Function block is is important to never delete:
%#codegen
because this allows the MATLAB code to function in Simulink.
The code inside the block is just the implementation of the final equation in Chapter 3.4 and 3.5 of Paul Uhing's Thesis. The outputs of the block are the acceleration of the pendulum's in pitch and roll, the acceleration of the yaw of the system, and the x and y global acceleration of the ground robot. Then MATLAB continuous time integrator blocks are used to get the corresponding velocities and positions. MATLAB function blocks do not do integration very well so it is easier just to calculate the accelerations and then use the Simulink blocks to integrate.
==== Actuator dynamics calculations ====
The actuator dynamics in general take in commands from the controller, mix them into individual motor commands and then calculate the force outputs of the motors. There are two actuator dynamics calculation subsystems. One for the propellers and one for the wheels. The controller output is calculated before these blocks and after the input command block. You just put whatever controller you want to use.
===== Propellers =====
The propeller subsystem takes in the the pitch and roll commands, the Euler angle velocities, the cart body velocities and the pitch and roll position. The pitch and roll inputs are mixed into actual motor commands using the ''Pitch_mixer'' and ''Roll_mixer''. These two MATLAB function blocks transform the command into something that can be used by the motor normalized between zero and one. Then the motor command, battery voltage and current motor velocity is passed into the motor MATLAB function blocks. These blocks calculate the acceleration of the propeller motors. That acceleration is integrated and the motor velocity is feedback into the motor block and then sent to the ''motor to force'' block. This MATLAB Function block uses the four propeller velocities, the angular velocities of the pendulum, and the body velocities of the cart. The output of the block is the total force output in the x and y pendulum axis. Finally there is a MATLAB function block, ''localAngleVel'' will calculate convert the global Euler angle velocities to to local body angular velocities. For how the model is generally used this last block isn't necessary but if you are going to have the pendulum do any maneuvers with large angular changes in both pitch and roll using this block will give you better results.
The calculations for all of this blocks come from Chapters 2.2, 3.6 and 3.7 of Paul Uhing's Thesis.
===== Wheels =====
The ''WheelForce'' subsystem of the RADA model takes in the heading, x and y controller outputs, the body linear velocities of the cart, the yaw velocity of the cart, the heading of the cart and finally takes in the x and y reference commands. This block then outputs the force produced by each of the four wheels.
The heading controller output command, the x and y velocity commands, the heading of the robot, and finally the x and y reference velocities are put into the wheel command mixing matrix, ''Wheel input mixer''. If you are using PIDs you will want to force this heading input to be zero all the time. This block calculate the command that should be sent to each wheel. These wheel commands pass though some saturation and scaling blocks and then are passed into the ''H-bridge model'' MATLAB Function block. This converts the controller output to a command for the motor between -1 and 1. This command is passed into the ''motor'' subsystems. These blocks take in this command the battery voltage and the velocity of the wheel which was summed from the body linear velocities of the cart and yaw velocity. This subsystem uses Simulink blocks to calculate the force produced by each wheel. The calcaultions done in this subsystem can be found in Chapters 3.5 and 3.7 of Paul Uhing's Thesis.
==== System commands ====
The system commands block is fairly strait forward. This subsystem just uses the From_Workspace Simulink blocks, step inputs and other Simulink source blocks to create the input reference commands for the simulation.
==== Body velocity calculations ====
This MATLAB Function block, ''body_vel'' calcuates the body linear velocities of the cart using the heading and global linear velocities of the cart to calculate the body linear velocities of the cart. The equation for this is in Chapter 2.2 of Paul Uhing's Thesis.
=== Modifying Simulink ===
==== Creating a new simulation ====
==== Modifying existing files ====
bd8d3d2dea229d0bf03024681b118455f03e008a
294
293
2016-08-08T18:43:35Z
Pfuhing
5
/* Modifying Simulink */
wikitext
text/x-wiki
== Simulink Setup ==
In order to use Simulink effectively you need to setup a few things. Iowa State will allow you download MATLAB and use a site license for free as a student. For more information about installing MATLAB using this site license look [http://it.engineering.iastate.edu/how-to/installing-matlab/ here.] Simulink comes with MATLAB. You should get MATLAB 2014b or latter to ensure the Simulink files from Paul Uhing's research repository will work with your installation of MATLAB.
Once the install is complete and MATLAB is registered you can open MATLAB up. Then change the folder MATLAB will work out of to a directory you will want to work form. It would be best to copy a few files from Paul Uhing's repository to help you get started. Inside of the RADA Research Repository go to ''MATLAB/RADA'' and copy ''modelParams_smallWheels_RADA.m'', ''Hbrigeest.mat'', ''Kvw_calc.mat'', ''Hmu_r_erisLargeWheels.mat'', ''LQI_recalc.m'', and ''RADA_ctrlSep.m'' from this directory to you new diectroy as these files will allow you to load the model parameters and controller designs used in Paul Uhing's thesis or find the most recent version of these files an copy them instead. It would also be good to copy and of the ''RADA_psiCtrl_v2.slx'' or ''RADA_psiCtrl_LQGsep.slx'' files here to sever as the base RADA simulation in your new directory. Finally, open te ''DataSets'' directory below the ''RADA'' directory can copy one of the ''RADA_LQG_compPID.mat'' files or ''RADA_LQG_sep.mat'' files because it will allow you to have input vector for the copied ''.slx'' Simulink file.
=== Setting up the MATLAB Workspace ===
Now in MATLAB with you working directory set to you new directory for test RADA simulations run ''modelParams_smallWheels_RADA.m'' from the MATLAB command line ten load the RADA ''.mat'' data file. Now in the Current Folder screen in MATLAB double click on the ''.slx'' and wait for it to open.
=== Settings in Simulink ===
When running a simulation RADA in simulink always make sure your solver is set to '''ode23t'''! The RADA model is a moderately stiff set of differential equations and ode45 the default solver will take an extremely long time to run simulaitons of RADA. You can set the run length to any length you want and then run the simulation.
=== Store Data from Simulink ===
All of the Simulink files in Paul Uhing's Research Repository output simulation data MATLAB structures contain the time and value arrays for important variables. After a simulation finishes these will show up as variables in the MATLAB Workspace. If you want to save any of these values for latter use select them in the MATLAB Workspace and right-click and select save or press ctrl+s to save these variables to a ''.mat'' file.
== Understanding and Modifying RADA Simulations ==
The Simulink models of RADA for Paul Uhing's Thesis is built to be fairly easy to understand. Normal Simulink blocks are used for routing signals and completing simple calculations. For more difficult calculations MATLAB Function blocks are used. These blocks allow you to write MATLAB code to complete some calculation. They can have inputs from the Simulink simulation and parameter inputs from the MATLAB Workspace. This makes complex calculations much easier to understand. The goal of using all of these tricks is to avoid creating a model that is a rat's nest of interconnecting blocks that is impossible trace any errors in the simulation. Understanding how the RADA model was put together wil help you understand how to modify this model and how to build your own models.
=== Components of the Model ===
The model is broken down into subsystems based off of sub-components of the actual system. There is a block for calculating the accelerations of RADA's body, two blocks for calculating the different actuator sets, producing commands to the system, and calculating intermediate values used by other blocks.
==== Body dynamics calculations ====
The body dynamics block (''RADA_BodyDynamcis_v2'') takes in Euler angle position and velocity of the pendulum (including yaw), the global velocity of the ground vehicle, the force produced by the propellers in the x body direction of the pendulum, the force produced by the propellers in the y body direction of the pendulum, and the force produced by each wheel. This block is a MATLAB Function block so it also has parameter inputs. For using MATLAB Function block is is important to never delete:
%#codegen
because this allows the MATLAB code to function in Simulink.
The code inside the block is just the implementation of the final equation in Chapter 3.4 of Paul Uhing's Thesis. The outputs of the block are the acceleration of the pendulum's in pitch and roll, the acceleration of the yaw of the system, and the x and y global acceleration of the ground robot. Then MATLAB continuous time integrator blocks are used to get the corresponding velocities and positions. MATLAB function blocks do not do integration very well so it is easier just to calculate the accelerations and then use the Simulink blocks to integrate.
== Simulink Setup ==
In order to use Simulink effectively you need to setup a few things. Iowa State will allow you download MATLAB and use a site license for free as a student. For more information about installing MATLAB using this site license look [http://it.engineering.iastate.edu/how-to/installing-matlab/ here.] Simulink comes with MATLAB. You should get MATLAB 2014b or latter to ensure the Simulink files from Paul Uhing's research repository will work with your installation of MATLAB.
Once the install is complete and MATLAB is registered you can open MATLAB up. Then change the folder MATLAB will work out of to a directory you will want to work form. It would be best to copy a few files from Paul Uhing's repository to help you get started. Inside of the RADA Research Repository go to ''MATLAB/RADA'' and copy ''modelParams_smallWheels_RADA.m'', ''Hbrigeest.mat'', ''Kvw_calc.mat'', ''Hmu_r_erisLargeWheels.mat'', ''LQI_recalc.m'', and ''RADA_ctrlSep.m'' from this directory to you new diectroy as these files will allow you to load the model parameters and controller designs used in Paul Uhing's thesis or find the most recent version of these files an copy them instead. It would also be good to copy and of the ''RADA_psiCtrl_v2.slx'' or ''RADA_psiCtrl_LQGsep.slx'' files here to sever as the base RADA simulation in your new directory. Finally, open te ''DataSets'' directory below the ''RADA'' directory can copy one of the ''RADA_LQG_compPID.mat'' files or ''RADA_LQG_sep.mat'' files because it will allow you to have input vector for the copied ''.slx'' Simulink file.
=== Setting up the MATLAB Workspace ===
Now in MATLAB with you working directory set to you new directory for test RADA simulations run ''modelParams_smallWheels_RADA.m'' from the MATLAB command line ten load the RADA ''.mat'' data file. Now in the Current Folder screen in MATLAB double click on the ''.slx'' and wait for it to open.
=== Settings in Simulink ===
When running a simulation RADA in simulink always make sure your solver is set to '''ode23t'''! The RADA model is a moderately stiff set of differential equations and ode45 the default solver will take an extremely long time to run simulaitons of RADA. You can set the run length to any length you want and then run the simulation.
=== Store Data from Simulink ===
All of the Simulink files in Paul Uhing's Research Repository output simulation data MATLAB structures contain the time and value arrays for important variables. After a simulation finishes these will show up as variables in the MATLAB Workspace. If you want to save any of these values for latter use select them in the MATLAB Workspace and right-click and select save or press ctrl+s to save these variables to a ''.mat'' file.
== Understanding and Modifying RADA Simulations ==
The Simulink models of RADA for Paul Uhing's Thesis is built to be fairly easy to understand. Normal Simulink blocks are used for routing signals and completing simple calculations. For more difficult calculations MATLAB Function blocks are used. These blocks allow you to write MATLAB code to complete some calculation. They can have inputs from the Simulink simulation and parameter inputs from the MATLAB Workspace. This makes complex calculations much easier to understand. The goal of using all of these tricks is to avoid creating a model that is a rat's nest of interconnecting blocks that is impossible trace any errors in the simulation. Understanding how the RADA model was put together wil help you understand how to modify this model and how to build your own models.
=== Components of the Model ===
The model is broken down into subsystems based off of sub-components of the actual system. There is a block for calculating the accelerations of RADA's body, two blocks for calculating the different actuator sets, producing commands to the system, and calculating intermediate values used by other blocks.
==== Body dynamics calculations ====
The body dynamics block (''RADA_BodyDynamcis_v2'') takes in Euler angle position and velocity of the pendulum (including yaw), the global velocity of the ground vehicle, the force produced by the propellers in the x body direction of the pendulum, the force produced by the propellers in the y body direction of the pendulum, and the force produced by each wheel. This block is a MATLAB Function block so it also has parameter inputs. For using MATLAB Function block is is important to never delete:
%#codegen
because this allows the MATLAB code to function in Simulink.
The code inside the block is just the implementation of the final equation in Chapter 3.4 and 3.5 of Paul Uhing's Thesis. The outputs of the block are the acceleration of the pendulum's in pitch and roll, the acceleration of the yaw of the system, and the x and y global acceleration of the ground robot. Then MATLAB continuous time integrator blocks are used to get the corresponding velocities and positions. MATLAB function blocks do not do integration very well so it is easier just to calculate the accelerations and then use the Simulink blocks to integrate.
==== Actuator dynamics calculations ====
The actuator dynamics in general take in commands from the controller, mix them into individual motor commands and then calculate the force outputs of the motors. There are two actuator dynamics calculation subsystems. One for the propellers and one for the wheels. The controller output is calculated before these blocks and after the input command block. You just put whatever controller you want to use.
===== Propellers =====
The propeller subsystem takes in the the pitch and roll commands, the Euler angle velocities, the cart body velocities and the pitch and roll position. The pitch and roll inputs are mixed into actual motor commands using the ''Pitch_mixer'' and ''Roll_mixer''. These two MATLAB function blocks transform the command into something that can be used by the motor normalized between zero and one. Then the motor command, battery voltage and current motor velocity is passed into the motor MATLAB function blocks. These blocks calculate the acceleration of the propeller motors. That acceleration is integrated and the motor velocity is feedback into the motor block and then sent to the ''motor to force'' block. This MATLAB Function block uses the four propeller velocities, the angular velocities of the pendulum, and the body velocities of the cart. The output of the block is the total force output in the x and y pendulum axis. Finally there is a MATLAB function block, ''localAngleVel'' will calculate convert the global Euler angle velocities to to local body angular velocities. For how the model is generally used this last block isn't necessary but if you are going to have the pendulum do any maneuvers with large angular changes in both pitch and roll using this block will give you better results.
The calculations for all of this blocks come from Chapters 2.2, 3.6 and 3.7 of Paul Uhing's Thesis.
===== Wheels =====
The ''WheelForce'' subsystem of the RADA model takes in the heading, x and y controller outputs, the body linear velocities of the cart, the yaw velocity of the cart, the heading of the cart and finally takes in the x and y reference commands. This block then outputs the force produced by each of the four wheels.
The heading controller output command, the x and y velocity commands, the heading of the robot, and finally the x and y reference velocities are put into the wheel command mixing matrix, ''Wheel input mixer''. If you are using PIDs you will want to force this heading input to be zero all the time. This block calculate the command that should be sent to each wheel. These wheel commands pass though some saturation and scaling blocks and then are passed into the ''H-bridge model'' MATLAB Function block. This converts the controller output to a command for the motor between -1 and 1. This command is passed into the ''motor'' subsystems. These blocks take in this command the battery voltage and the velocity of the wheel which was summed from the body linear velocities of the cart and yaw velocity. This subsystem uses Simulink blocks to calculate the force produced by each wheel. The calcaultions done in this subsystem can be found in Chapters 3.5 and 3.7 of Paul Uhing's Thesis.
==== System commands ====
The system commands block is fairly strait forward. This subsystem just uses the From_Workspace Simulink blocks, step inputs and other Simulink source blocks to create the input reference commands for the simulation.
==== Body velocity calculations ====
This MATLAB Function block, ''body_vel'' calcuates the body linear velocities of the cart using the heading and global linear velocities of the cart to calculate the body linear velocities of the cart. The equation for this is in Chapter 2.2 of Paul Uhing's Thesis.
=== Modifying Simulink ===
When it comes to modifying Simulink there are two options. you can either create a new simulation or modify an existing file. If you are working with the RADA system you should make sure you are using MATLAB 2014b or latter to ensure the Simulink files form Paul Uhing's research will work correctly. Ether way you will need to start MATLAB and set your working directory to the folder that you want to work out of. Then you can open Simulink by opening a Simulink model (file extension ''.xls'' or ''.mdl'') or by typing ''simulink'' into the MATLAB command line. Using the command line will open the Simulink Library window. Either way in newer versions of MATLAB it tends to take Simulink a while to open from MATLAB.
==== Creating a new simulation ====
==== Modifying existing files ====
c2acd46bd58e60b34be71704e9a04ef8de9c11c7
295
294
2016-08-08T19:08:54Z
Pfuhing
5
/* Creating a new simulation */
wikitext
text/x-wiki
== Simulink Setup ==
In order to use Simulink effectively you need to setup a few things. Iowa State will allow you download MATLAB and use a site license for free as a student. For more information about installing MATLAB using this site license look [http://it.engineering.iastate.edu/how-to/installing-matlab/ here.] Simulink comes with MATLAB. You should get MATLAB 2014b or latter to ensure the Simulink files from Paul Uhing's research repository will work with your installation of MATLAB.
Once the install is complete and MATLAB is registered you can open MATLAB up. Then change the folder MATLAB will work out of to a directory you will want to work form. It would be best to copy a few files from Paul Uhing's repository to help you get started. Inside of the RADA Research Repository go to ''MATLAB/RADA'' and copy ''modelParams_smallWheels_RADA.m'', ''Hbrigeest.mat'', ''Kvw_calc.mat'', ''Hmu_r_erisLargeWheels.mat'', ''LQI_recalc.m'', and ''RADA_ctrlSep.m'' from this directory to you new diectroy as these files will allow you to load the model parameters and controller designs used in Paul Uhing's thesis or find the most recent version of these files an copy them instead. It would also be good to copy and of the ''RADA_psiCtrl_v2.slx'' or ''RADA_psiCtrl_LQGsep.slx'' files here to sever as the base RADA simulation in your new directory. Finally, open te ''DataSets'' directory below the ''RADA'' directory can copy one of the ''RADA_LQG_compPID.mat'' files or ''RADA_LQG_sep.mat'' files because it will allow you to have input vector for the copied ''.slx'' Simulink file.
=== Setting up the MATLAB Workspace ===
Now in MATLAB with you working directory set to you new directory for test RADA simulations run ''modelParams_smallWheels_RADA.m'' from the MATLAB command line ten load the RADA ''.mat'' data file. Now in the Current Folder screen in MATLAB double click on the ''.slx'' and wait for it to open.
=== Settings in Simulink ===
When running a simulation RADA in simulink always make sure your solver is set to '''ode23t'''! The RADA model is a moderately stiff set of differential equations and ode45 the default solver will take an extremely long time to run simulaitons of RADA. You can set the run length to any length you want and then run the simulation.
=== Store Data from Simulink ===
All of the Simulink files in Paul Uhing's Research Repository output simulation data MATLAB structures contain the time and value arrays for important variables. After a simulation finishes these will show up as variables in the MATLAB Workspace. If you want to save any of these values for latter use select them in the MATLAB Workspace and right-click and select save or press ctrl+s to save these variables to a ''.mat'' file.
== Understanding and Modifying RADA Simulations ==
The Simulink models of RADA for Paul Uhing's Thesis is built to be fairly easy to understand. Normal Simulink blocks are used for routing signals and completing simple calculations. For more difficult calculations MATLAB Function blocks are used. These blocks allow you to write MATLAB code to complete some calculation. They can have inputs from the Simulink simulation and parameter inputs from the MATLAB Workspace. This makes complex calculations much easier to understand. The goal of using all of these tricks is to avoid creating a model that is a rat's nest of interconnecting blocks that is impossible trace any errors in the simulation. Understanding how the RADA model was put together wil help you understand how to modify this model and how to build your own models.
=== Components of the Model ===
The model is broken down into subsystems based off of sub-components of the actual system. There is a block for calculating the accelerations of RADA's body, two blocks for calculating the different actuator sets, producing commands to the system, and calculating intermediate values used by other blocks.
==== Body dynamics calculations ====
The body dynamics block (''RADA_BodyDynamcis_v2'') takes in Euler angle position and velocity of the pendulum (including yaw), the global velocity of the ground vehicle, the force produced by the propellers in the x body direction of the pendulum, the force produced by the propellers in the y body direction of the pendulum, and the force produced by each wheel. This block is a MATLAB Function block so it also has parameter inputs. For using MATLAB Function block is is important to never delete:
%#codegen
because this allows the MATLAB code to function in Simulink.
The code inside the block is just the implementation of the final equation in Chapter 3.4 of Paul Uhing's Thesis. The outputs of the block are the acceleration of the pendulum's in pitch and roll, the acceleration of the yaw of the system, and the x and y global acceleration of the ground robot. Then MATLAB continuous time integrator blocks are used to get the corresponding velocities and positions. MATLAB function blocks do not do integration very well so it is easier just to calculate the accelerations and then use the Simulink blocks to integrate.
== Simulink Setup ==
In order to use Simulink effectively you need to setup a few things. Iowa State will allow you download MATLAB and use a site license for free as a student. For more information about installing MATLAB using this site license look [http://it.engineering.iastate.edu/how-to/installing-matlab/ here.] Simulink comes with MATLAB. You should get MATLAB 2014b or latter to ensure the Simulink files from Paul Uhing's research repository will work with your installation of MATLAB.
Once the install is complete and MATLAB is registered you can open MATLAB up. Then change the folder MATLAB will work out of to a directory you will want to work form. It would be best to copy a few files from Paul Uhing's repository to help you get started. Inside of the RADA Research Repository go to ''MATLAB/RADA'' and copy ''modelParams_smallWheels_RADA.m'', ''Hbrigeest.mat'', ''Kvw_calc.mat'', ''Hmu_r_erisLargeWheels.mat'', ''LQI_recalc.m'', and ''RADA_ctrlSep.m'' from this directory to you new diectroy as these files will allow you to load the model parameters and controller designs used in Paul Uhing's thesis or find the most recent version of these files an copy them instead. It would also be good to copy and of the ''RADA_psiCtrl_v2.slx'' or ''RADA_psiCtrl_LQGsep.slx'' files here to sever as the base RADA simulation in your new directory. Finally, open te ''DataSets'' directory below the ''RADA'' directory can copy one of the ''RADA_LQG_compPID.mat'' files or ''RADA_LQG_sep.mat'' files because it will allow you to have input vector for the copied ''.slx'' Simulink file.
=== Setting up the MATLAB Workspace ===
Now in MATLAB with you working directory set to you new directory for test RADA simulations run ''modelParams_smallWheels_RADA.m'' from the MATLAB command line ten load the RADA ''.mat'' data file. Now in the Current Folder screen in MATLAB double click on the ''.slx'' and wait for it to open.
=== Settings in Simulink ===
When running a simulation RADA in simulink always make sure your solver is set to '''ode23t'''! The RADA model is a moderately stiff set of differential equations and ode45 the default solver will take an extremely long time to run simulaitons of RADA. You can set the run length to any length you want and then run the simulation.
=== Store Data from Simulink ===
All of the Simulink files in Paul Uhing's Research Repository output simulation data MATLAB structures contain the time and value arrays for important variables. After a simulation finishes these will show up as variables in the MATLAB Workspace. If you want to save any of these values for latter use select them in the MATLAB Workspace and right-click and select save or press ctrl+s to save these variables to a ''.mat'' file.
== Understanding and Modifying RADA Simulations ==
The Simulink models of RADA for Paul Uhing's Thesis is built to be fairly easy to understand. Normal Simulink blocks are used for routing signals and completing simple calculations. For more difficult calculations MATLAB Function blocks are used. These blocks allow you to write MATLAB code to complete some calculation. They can have inputs from the Simulink simulation and parameter inputs from the MATLAB Workspace. This makes complex calculations much easier to understand. The goal of using all of these tricks is to avoid creating a model that is a rat's nest of interconnecting blocks that is impossible trace any errors in the simulation. Understanding how the RADA model was put together wil help you understand how to modify this model and how to build your own models.
=== Components of the Model ===
The model is broken down into subsystems based off of sub-components of the actual system. There is a block for calculating the accelerations of RADA's body, two blocks for calculating the different actuator sets, producing commands to the system, and calculating intermediate values used by other blocks.
==== Body dynamics calculations ====
The body dynamics block (''RADA_BodyDynamcis_v2'') takes in Euler angle position and velocity of the pendulum (including yaw), the global velocity of the ground vehicle, the force produced by the propellers in the x body direction of the pendulum, the force produced by the propellers in the y body direction of the pendulum, and the force produced by each wheel. This block is a MATLAB Function block so it also has parameter inputs. For using MATLAB Function block is is important to never delete:
%#codegen
because this allows the MATLAB code to function in Simulink.
The code inside the block is just the implementation of the final equation in Chapter 3.4 and 3.5 of Paul Uhing's Thesis. The outputs of the block are the acceleration of the pendulum's in pitch and roll, the acceleration of the yaw of the system, and the x and y global acceleration of the ground robot. Then MATLAB continuous time integrator blocks are used to get the corresponding velocities and positions. MATLAB function blocks do not do integration very well so it is easier just to calculate the accelerations and then use the Simulink blocks to integrate.
==== Actuator dynamics calculations ====
The actuator dynamics in general take in commands from the controller, mix them into individual motor commands and then calculate the force outputs of the motors. There are two actuator dynamics calculation subsystems. One for the propellers and one for the wheels. The controller output is calculated before these blocks and after the input command block. You just put whatever controller you want to use.
===== Propellers =====
The propeller subsystem takes in the the pitch and roll commands, the Euler angle velocities, the cart body velocities and the pitch and roll position. The pitch and roll inputs are mixed into actual motor commands using the ''Pitch_mixer'' and ''Roll_mixer''. These two MATLAB function blocks transform the command into something that can be used by the motor normalized between zero and one. Then the motor command, battery voltage and current motor velocity is passed into the motor MATLAB function blocks. These blocks calculate the acceleration of the propeller motors. That acceleration is integrated and the motor velocity is feedback into the motor block and then sent to the ''motor to force'' block. This MATLAB Function block uses the four propeller velocities, the angular velocities of the pendulum, and the body velocities of the cart. The output of the block is the total force output in the x and y pendulum axis. Finally there is a MATLAB function block, ''localAngleVel'' will calculate convert the global Euler angle velocities to to local body angular velocities. For how the model is generally used this last block isn't necessary but if you are going to have the pendulum do any maneuvers with large angular changes in both pitch and roll using this block will give you better results.
The calculations for all of this blocks come from Chapters 2.2, 3.6 and 3.7 of Paul Uhing's Thesis.
===== Wheels =====
The ''WheelForce'' subsystem of the RADA model takes in the heading, x and y controller outputs, the body linear velocities of the cart, the yaw velocity of the cart, the heading of the cart and finally takes in the x and y reference commands. This block then outputs the force produced by each of the four wheels.
The heading controller output command, the x and y velocity commands, the heading of the robot, and finally the x and y reference velocities are put into the wheel command mixing matrix, ''Wheel input mixer''. If you are using PIDs you will want to force this heading input to be zero all the time. This block calculate the command that should be sent to each wheel. These wheel commands pass though some saturation and scaling blocks and then are passed into the ''H-bridge model'' MATLAB Function block. This converts the controller output to a command for the motor between -1 and 1. This command is passed into the ''motor'' subsystems. These blocks take in this command the battery voltage and the velocity of the wheel which was summed from the body linear velocities of the cart and yaw velocity. This subsystem uses Simulink blocks to calculate the force produced by each wheel. The calcaultions done in this subsystem can be found in Chapters 3.5 and 3.7 of Paul Uhing's Thesis.
==== System commands ====
The system commands block is fairly strait forward. This subsystem just uses the From_Workspace Simulink blocks, step inputs and other Simulink source blocks to create the input reference commands for the simulation.
==== Body velocity calculations ====
This MATLAB Function block, ''body_vel'' calcuates the body linear velocities of the cart using the heading and global linear velocities of the cart to calculate the body linear velocities of the cart. The equation for this is in Chapter 2.2 of Paul Uhing's Thesis.
=== Modifying Simulink ===
When it comes to modifying Simulink there are two options. you can either create a new simulation or modify an existing file. If you are working with the RADA system you should make sure you are using MATLAB 2014b or latter to ensure the Simulink files form Paul Uhing's research will work correctly. Ether way you will need to start MATLAB and set your working directory to the folder that you want to work out of. Then you can open Simulink by opening a Simulink model (file extension ''.xls'' or ''.mdl'') or by typing ''simulink'' into the MATLAB command line. Using the command line will open the Simulink Library window. Either way in newer versions of MATLAB it tends to take Simulink a while to open from MATLAB.
==== Creating a new simulation ====
To create a new Simulink model either in an existing model ''File->New->Model'' or you can click on the new model button. You can also use the new model button in the Simulink Library window. Now a new model page will open up. The first thing you will want to do if you are going to use the model for RADA is to change the ordinary differential equations (ODE) solver. In Simulink the ODE solver will default to the continuous time solver ''ode45'' but this solver doesn't work well for stiff differential equations. Because RADA is a moderately stiff system you will want to change the solver to the continuous time ODE solver ''ode23t''. Do this by going to ''Simulation->Model Configuration Parameters'' or press ''ctrl+E''. This opens up the model parameters panel. Here you have all the same options you would if you were using the ODE solver in MATLAB. In the solver drop down menu choose ''ode23t'' and then click ''Apply'' or ''OK''.
Now you can build the model however you want or copy in systems from other models.
==== Modifying existing files ====
9a8ab20c1004bbdd62541bbeb457474ddb5a15b8
296
295
2016-08-08T19:18:09Z
Pfuhing
5
/* Modifying existing files */
wikitext
text/x-wiki
== Simulink Setup ==
In order to use Simulink effectively you need to setup a few things. Iowa State will allow you download MATLAB and use a site license for free as a student. For more information about installing MATLAB using this site license look [http://it.engineering.iastate.edu/how-to/installing-matlab/ here.] Simulink comes with MATLAB. You should get MATLAB 2014b or latter to ensure the Simulink files from Paul Uhing's research repository will work with your installation of MATLAB.
Once the install is complete and MATLAB is registered you can open MATLAB up. Then change the folder MATLAB will work out of to a directory you will want to work form. It would be best to copy a few files from Paul Uhing's repository to help you get started. Inside of the RADA Research Repository go to ''MATLAB/RADA'' and copy ''modelParams_smallWheels_RADA.m'', ''Hbrigeest.mat'', ''Kvw_calc.mat'', ''Hmu_r_erisLargeWheels.mat'', ''LQI_recalc.m'', and ''RADA_ctrlSep.m'' from this directory to you new diectroy as these files will allow you to load the model parameters and controller designs used in Paul Uhing's thesis or find the most recent version of these files an copy them instead. It would also be good to copy and of the ''RADA_psiCtrl_v2.slx'' or ''RADA_psiCtrl_LQGsep.slx'' files here to sever as the base RADA simulation in your new directory. Finally, open te ''DataSets'' directory below the ''RADA'' directory can copy one of the ''RADA_LQG_compPID.mat'' files or ''RADA_LQG_sep.mat'' files because it will allow you to have input vector for the copied ''.slx'' Simulink file.
=== Setting up the MATLAB Workspace ===
Now in MATLAB with you working directory set to you new directory for test RADA simulations run ''modelParams_smallWheels_RADA.m'' from the MATLAB command line ten load the RADA ''.mat'' data file. Now in the Current Folder screen in MATLAB double click on the ''.slx'' and wait for it to open.
=== Settings in Simulink ===
When running a simulation RADA in simulink always make sure your solver is set to '''ode23t'''! The RADA model is a moderately stiff set of differential equations and ode45 the default solver will take an extremely long time to run simulaitons of RADA. You can set the run length to any length you want and then run the simulation.
=== Store Data from Simulink ===
All of the Simulink files in Paul Uhing's Research Repository output simulation data MATLAB structures contain the time and value arrays for important variables. After a simulation finishes these will show up as variables in the MATLAB Workspace. If you want to save any of these values for latter use select them in the MATLAB Workspace and right-click and select save or press ctrl+s to save these variables to a ''.mat'' file.
== Understanding and Modifying RADA Simulations ==
The Simulink models of RADA for Paul Uhing's Thesis is built to be fairly easy to understand. Normal Simulink blocks are used for routing signals and completing simple calculations. For more difficult calculations MATLAB Function blocks are used. These blocks allow you to write MATLAB code to complete some calculation. They can have inputs from the Simulink simulation and parameter inputs from the MATLAB Workspace. This makes complex calculations much easier to understand. The goal of using all of these tricks is to avoid creating a model that is a rat's nest of interconnecting blocks that is impossible trace any errors in the simulation. Understanding how the RADA model was put together wil help you understand how to modify this model and how to build your own models.
=== Components of the Model ===
The model is broken down into subsystems based off of sub-components of the actual system. There is a block for calculating the accelerations of RADA's body, two blocks for calculating the different actuator sets, producing commands to the system, and calculating intermediate values used by other blocks.
==== Body dynamics calculations ====
The body dynamics block (''RADA_BodyDynamcis_v2'') takes in Euler angle position and velocity of the pendulum (including yaw), the global velocity of the ground vehicle, the force produced by the propellers in the x body direction of the pendulum, the force produced by the propellers in the y body direction of the pendulum, and the force produced by each wheel. This block is a MATLAB Function block so it also has parameter inputs. For using MATLAB Function block is is important to never delete:
%#codegen
because this allows the MATLAB code to function in Simulink.
The code inside the block is just the implementation of the final equation in Chapter 3.4 of Paul Uhing's Thesis. The outputs of the block are the acceleration of the pendulum's in pitch and roll, the acceleration of the yaw of the system, and the x and y global acceleration of the ground robot. Then MATLAB continuous time integrator blocks are used to get the corresponding velocities and positions. MATLAB function blocks do not do integration very well so it is easier just to calculate the accelerations and then use the Simulink blocks to integrate.
== Simulink Setup ==
In order to use Simulink effectively you need to setup a few things. Iowa State will allow you download MATLAB and use a site license for free as a student. For more information about installing MATLAB using this site license look [http://it.engineering.iastate.edu/how-to/installing-matlab/ here.] Simulink comes with MATLAB. You should get MATLAB 2014b or latter to ensure the Simulink files from Paul Uhing's research repository will work with your installation of MATLAB.
Once the install is complete and MATLAB is registered you can open MATLAB up. Then change the folder MATLAB will work out of to a directory you will want to work form. It would be best to copy a few files from Paul Uhing's repository to help you get started. Inside of the RADA Research Repository go to ''MATLAB/RADA'' and copy ''modelParams_smallWheels_RADA.m'', ''Hbrigeest.mat'', ''Kvw_calc.mat'', ''Hmu_r_erisLargeWheels.mat'', ''LQI_recalc.m'', and ''RADA_ctrlSep.m'' from this directory to you new diectroy as these files will allow you to load the model parameters and controller designs used in Paul Uhing's thesis or find the most recent version of these files an copy them instead. It would also be good to copy and of the ''RADA_psiCtrl_v2.slx'' or ''RADA_psiCtrl_LQGsep.slx'' files here to sever as the base RADA simulation in your new directory. Finally, open te ''DataSets'' directory below the ''RADA'' directory can copy one of the ''RADA_LQG_compPID.mat'' files or ''RADA_LQG_sep.mat'' files because it will allow you to have input vector for the copied ''.slx'' Simulink file.
=== Setting up the MATLAB Workspace ===
Now in MATLAB with you working directory set to you new directory for test RADA simulations run ''modelParams_smallWheels_RADA.m'' from the MATLAB command line ten load the RADA ''.mat'' data file. Now in the Current Folder screen in MATLAB double click on the ''.slx'' and wait for it to open.
=== Settings in Simulink ===
When running a simulation RADA in simulink always make sure your solver is set to '''ode23t'''! The RADA model is a moderately stiff set of differential equations and ode45 the default solver will take an extremely long time to run simulaitons of RADA. You can set the run length to any length you want and then run the simulation.
=== Store Data from Simulink ===
All of the Simulink files in Paul Uhing's Research Repository output simulation data MATLAB structures contain the time and value arrays for important variables. After a simulation finishes these will show up as variables in the MATLAB Workspace. If you want to save any of these values for latter use select them in the MATLAB Workspace and right-click and select save or press ctrl+s to save these variables to a ''.mat'' file.
== Understanding and Modifying RADA Simulations ==
The Simulink models of RADA for Paul Uhing's Thesis is built to be fairly easy to understand. Normal Simulink blocks are used for routing signals and completing simple calculations. For more difficult calculations MATLAB Function blocks are used. These blocks allow you to write MATLAB code to complete some calculation. They can have inputs from the Simulink simulation and parameter inputs from the MATLAB Workspace. This makes complex calculations much easier to understand. The goal of using all of these tricks is to avoid creating a model that is a rat's nest of interconnecting blocks that is impossible trace any errors in the simulation. Understanding how the RADA model was put together wil help you understand how to modify this model and how to build your own models.
=== Components of the Model ===
The model is broken down into subsystems based off of sub-components of the actual system. There is a block for calculating the accelerations of RADA's body, two blocks for calculating the different actuator sets, producing commands to the system, and calculating intermediate values used by other blocks.
==== Body dynamics calculations ====
The body dynamics block (''RADA_BodyDynamcis_v2'') takes in Euler angle position and velocity of the pendulum (including yaw), the global velocity of the ground vehicle, the force produced by the propellers in the x body direction of the pendulum, the force produced by the propellers in the y body direction of the pendulum, and the force produced by each wheel. This block is a MATLAB Function block so it also has parameter inputs. For using MATLAB Function block is is important to never delete:
%#codegen
because this allows the MATLAB code to function in Simulink.
The code inside the block is just the implementation of the final equation in Chapter 3.4 and 3.5 of Paul Uhing's Thesis. The outputs of the block are the acceleration of the pendulum's in pitch and roll, the acceleration of the yaw of the system, and the x and y global acceleration of the ground robot. Then MATLAB continuous time integrator blocks are used to get the corresponding velocities and positions. MATLAB function blocks do not do integration very well so it is easier just to calculate the accelerations and then use the Simulink blocks to integrate.
==== Actuator dynamics calculations ====
The actuator dynamics in general take in commands from the controller, mix them into individual motor commands and then calculate the force outputs of the motors. There are two actuator dynamics calculation subsystems. One for the propellers and one for the wheels. The controller output is calculated before these blocks and after the input command block. You just put whatever controller you want to use.
===== Propellers =====
The propeller subsystem takes in the the pitch and roll commands, the Euler angle velocities, the cart body velocities and the pitch and roll position. The pitch and roll inputs are mixed into actual motor commands using the ''Pitch_mixer'' and ''Roll_mixer''. These two MATLAB function blocks transform the command into something that can be used by the motor normalized between zero and one. Then the motor command, battery voltage and current motor velocity is passed into the motor MATLAB function blocks. These blocks calculate the acceleration of the propeller motors. That acceleration is integrated and the motor velocity is feedback into the motor block and then sent to the ''motor to force'' block. This MATLAB Function block uses the four propeller velocities, the angular velocities of the pendulum, and the body velocities of the cart. The output of the block is the total force output in the x and y pendulum axis. Finally there is a MATLAB function block, ''localAngleVel'' will calculate convert the global Euler angle velocities to to local body angular velocities. For how the model is generally used this last block isn't necessary but if you are going to have the pendulum do any maneuvers with large angular changes in both pitch and roll using this block will give you better results.
The calculations for all of this blocks come from Chapters 2.2, 3.6 and 3.7 of Paul Uhing's Thesis.
===== Wheels =====
The ''WheelForce'' subsystem of the RADA model takes in the heading, x and y controller outputs, the body linear velocities of the cart, the yaw velocity of the cart, the heading of the cart and finally takes in the x and y reference commands. This block then outputs the force produced by each of the four wheels.
The heading controller output command, the x and y velocity commands, the heading of the robot, and finally the x and y reference velocities are put into the wheel command mixing matrix, ''Wheel input mixer''. If you are using PIDs you will want to force this heading input to be zero all the time. This block calculate the command that should be sent to each wheel. These wheel commands pass though some saturation and scaling blocks and then are passed into the ''H-bridge model'' MATLAB Function block. This converts the controller output to a command for the motor between -1 and 1. This command is passed into the ''motor'' subsystems. These blocks take in this command the battery voltage and the velocity of the wheel which was summed from the body linear velocities of the cart and yaw velocity. This subsystem uses Simulink blocks to calculate the force produced by each wheel. The calcaultions done in this subsystem can be found in Chapters 3.5 and 3.7 of Paul Uhing's Thesis.
==== System commands ====
The system commands block is fairly strait forward. This subsystem just uses the From_Workspace Simulink blocks, step inputs and other Simulink source blocks to create the input reference commands for the simulation.
==== Body velocity calculations ====
This MATLAB Function block, ''body_vel'' calcuates the body linear velocities of the cart using the heading and global linear velocities of the cart to calculate the body linear velocities of the cart. The equation for this is in Chapter 2.2 of Paul Uhing's Thesis.
=== Modifying Simulink ===
When it comes to modifying Simulink there are two options. you can either create a new simulation or modify an existing file. If you are working with the RADA system you should make sure you are using MATLAB 2014b or latter to ensure the Simulink files form Paul Uhing's research will work correctly. Ether way you will need to start MATLAB and set your working directory to the folder that you want to work out of. Then you can open Simulink by opening a Simulink model (file extension ''.xls'' or ''.mdl'') or by typing ''simulink'' into the MATLAB command line. Using the command line will open the Simulink Library window. Either way in newer versions of MATLAB it tends to take Simulink a while to open from MATLAB.
==== Creating a new simulation ====
To create a new Simulink model either in an existing model ''File->New->Model'' or you can click on the new model button. You can also use the new model button in the Simulink Library window. Now a new model page will open up. The first thing you will want to do if you are going to use the model for RADA is to change the ordinary differential equations (ODE) solver. In Simulink the ODE solver will default to the continuous time solver ''ode45'' but this solver doesn't work well for stiff differential equations. Because RADA is a moderately stiff system you will want to change the solver to the continuous time ODE solver ''ode23t''. Do this by going to ''Simulation->Model Configuration Parameters'' or press ''ctrl+E''. This opens up the model parameters panel. Here you have all the same options you would if you were using the ODE solver in MATLAB. In the solver drop down menu choose ''ode23t'' and then click ''Apply'' or ''OK''.
Now you can build the model however you want or copy in systems from other models.
==== Modifying existing files ====
You can simply open the Simulink file you want to modify. If you are going to make a large number of modifications or delete a lot of things it would be wise to save this model as a new file and modify the new file so you have a backup incase the modified model has problems. This will make debugging much easier. When you do this just make sure the ODE solver is ''ode23t'' as it may default back to ''ode45''. If you are just making small modifications you can just modify the same file.
b12da5e4555e438a3dc2bea91d9503aad299497b
Using Robotic Agriculture Data Acquisition (RADA) for Research Use
0
48
278
172
2016-08-04T18:54:16Z
Pfuhing
5
wikitext
text/x-wiki
This page discusses the RADA platform for research used. If you want information about the RADA platform see [http://wikis.ece.iastate.edu/robotic-agriculture-data-acquisition/index.php/Main_Page RADA Senior Design Project].
This page will discuss two important issues for using the RADA platform for research:
*[[Data Collection and Simulation Comparison]]
*[[Setting up and Modifying RADA Simulations]]
*[[Test]]
The page on data collection and simulation comparison will discus how to set a test of RADA and then take the logged data and compare it to a simulation of RADA in Simulink using the model developed for Paul Uhing's thesis. While the page on setting up and modifing RADA simulations will discuss how RADA Simulink simulations are currently structured and other important information for creating your own Simulink simulations of RADA.
209bd19c78a69a26d705b28a728829f757b6052e
283
278
2016-08-04T19:35:26Z
Pfuhing
5
wikitext
text/x-wiki
This page discusses the RADA platform for research used. If you want information about the RADA platform see [http://wikis.ece.iastate.edu/robotic-agriculture-data-acquisition/index.php/Main_Page RADA Senior Design Project].
This page will discuss two important issues for using the RADA platform for research:
*[[Data Collection and Simulation Comparison]]
*[[Setting up and Modifying RADA Simulations]]
The page on data collection and simulation comparison will discus how to set a test of RADA and then take the logged data and compare it to a simulation of RADA in Simulink using the model developed for Paul Uhing's thesis. While the page on setting up and modifing RADA simulations will discuss how RADA Simulink simulations are currently structured and other important information for creating your own Simulink simulations of RADA.
086138a5c9ed2365ec2d4a88a5cb83a0f9f45b47
Test
0
82
279
2016-08-04T19:23:55Z
Pfuhing
5
New page: test
wikitext
text/x-wiki
test
a94a8fe5ccb19ba61c4c0873d391e987982fbbd3
280
279
2016-08-04T19:30:24Z
Pfuhing
5
wikitext
text/x-wiki
<div id="top" class="navigation">
<div class="tabs">
<ul>
<li>[[index.html|<span>Main Page</span>]]</li>
<li>[[annotated.html|<span>Classes</span>]]</li>
<li>[[files.html|<span>Files</span>]]</li>
-----
Generated on 28 Jul 2016 for RADA Reserarch Code Base by [http://www.doxygen.org/index.html [[File:doxygen.png|class=footer|doxygen]]] 1.6.1
95f6c53612c9664581c7bc8fb23b4df582707ab1
281
280
2016-08-04T19:32:23Z
Pfuhing
5
wikitext
text/x-wiki
<span>RADA Reserarch Code Base </span><br />
<br />
<br />
= Class Index =
== Class List ==
Here are the classes, structs, unions and interfaces with brief descriptions:
= File Index =
== File List ==
Here is a list of all files with brief descriptions:
= Class Documentation =
<span>#include <math><</math>motor_controller_common.h<math>></math></span>
=== Public Attributes ===
double STATES_C
double STATES_C
double STATES_CSTATES_C
double STATES_CINPUTS_C
double OUTPUTS_CSTATES_C
double OUTPUTS_CINPUTS_C
double OUTPUTS_C
double INPUTS_C
double
double
double
double
double
double
double
=== Member Data Documentation ===
[structCTRLSS_a99323b1af830e7170af3eb72aa41d8b3] [structCTRLSS_a751b08ff03f811cd299a275d64a1776a] [structCTRLSS_a3ea95aceed6524af85a73066285a25bd] [structCTRLSS_a01a7190f80d6033577efa0caf702a9de] [structCTRLSS_a3ddf713d4d6a47c452bb2c4f36601720] [structCTRLSS_acc76fcf689629f6d35cb37ef7274421d] [structCTRLSS_a029e4fe6ce170bcb874a0514af186198] [structCTRLSS_a6ce9144e59b5a087b8014e1f58df8292] [structCTRLSS_aea6bc624a0ebf341819b39020909dd04] [structCTRLSS_aab84633e6cc98bb274a137e0dbe0632e] [structCTRLSS_ad0c4dfb12c67eb1eebbe9ecb33ea81c7] [structCTRLSS_a2d457a9fd6b55eb5a445c2dc98ddd7d4] [structCTRLSS_a014cd2f9819f50a41b6a0e685f99be06] [structCTRLSS_a1dd57a341230062f91ffde1ac18f75d4] [structCTRLSS_ad22a1976dcc9969f365d01e0ef0a617e]
The documentation for this struct was generated from the following file:
<span>#include <math><</math>motor_controller_common.h<math>></math></span>
=== Public Attributes ===
double STATES_C_LOSS
double STATES_C_LOSS
double OUTPUTS_C_LOSS
double INPUT2_C_LOSS
double OUT1_C_LOSS
double INPUT2_C_LOSS
double INPUTS_C_LOSS
double OUT1_C_LOSS
double
double
double
double
double
double
double
=== Member Data Documentation ===
[structCTRLSS__loss_a904658b1581cfaf90efcef9cf0f5d48c] [structCTRLSS__loss_ac523ba7a0ee64b1618fdf9346e25bbd0] [structCTRLSS__loss_aad426c6e52a67fc40855671347b0872c] [structCTRLSS__loss_af3504df76d7647c9557e0382cdd5af03] [structCTRLSS__loss_ad9c1f4d4229875c7a8757134e3262f1a] [structCTRLSS__loss_a3306c7c3457a90cfd8913969acd07489] [structCTRLSS__loss_ab6a6d80b9d3bf0609025c2773a03aa6a] [structCTRLSS__loss_a94b30d3d55be796a780f1b7f6ff5d4fd] [structCTRLSS__loss_acfcc19f41c9e4d6ad41763780df431fe] [structCTRLSS__loss_a68ad7dacfd6564154b0ababc73adadb8] [structCTRLSS__loss_a2477cdabb56e7b05643566b0bf54a681] [structCTRLSS__loss_aec54a6d6e7de19b0025d9b5ba71302e8] [structCTRLSS__loss_a2241843bf580dae1221eca4bc7391094] [structCTRLSS__loss_a522a79b355319b1d7f76787ee267d049] [structCTRLSS__loss_a65d0a6c66bb0149fade8a9253cde83af]
The documentation for this struct was generated from the following file:
<span>#include <math><</math>motor_controller_common.h<math>></math></span>
=== Public Attributes ===
double
double
double
double
double
double
float
float
float
float
float
float
float
float
float
float
float
float
float
float
float
float
float
float
float
short
long
float
short
long
float
short
long
float
short
long
float
int
int
struct
struct
=== Member Data Documentation ===
[structERIS_a594f58e4b65b38fdaab0f83bb7bc8293] [structERIS_affb5711d1d76fd40c46d868b5f6927aa] [structERIS_ad945a9871aa3ed47039939d88f9b2299] [structERIS_a4c8be3873d1d6d36d2adebb5583691fb] [structERIS_a112c7b15e1c3b9e357f7efd450311e8c] [structERIS_a85a4abeca56252fabbf184cb3322a7d6] [structERIS_a9928bd6601057058bc98f0f1eb872292] [structERIS_a869ad31293ee6b745995e7ffe1e6a0f3] [structERIS_ad9b624848a4ec324a96976aa405b045b] [structERIS_a7be16859eb75730aaf5ea03730eeff89] [structERIS_a9fb27e63c72b45f039b459c121057750] [structERIS_a9d0eab06fbf935d7ce8a07ec9f6abda8] [structERIS_a455b48179fcb3643a44977f21ef2bf92] [structERIS_a9d884151e04cd0868cb6bb12cec77add] [structERIS_aaefa4f638c81e80f8b0cfb61a9730566] [structERIS_a63236f07dd96e08e0771f229d100eeeb] [structERIS_aef28562d61240755434169358ea97368] [structERIS_afec79f417cb04b2dcfb9c56a63736014] [structERIS_ae418f284e890ee3c7e0c15df949395c2] [structERIS_ab5d12b6188aa05281c30d1c13d618f4b] [structERIS_a92dc86b172980adc160aeb94a7e27f8d] [structERIS_ad87f4be8f56b23c4e94c5d65c5db2384] [structERIS_a28f58b5c3dd3b40b010ac65650e5eeeb] [structERIS_a04871634308c93a163323a16bbb3b874] [structERIS_a2605317a4567b84182bd96e85af624b5] [structERIS_aa4385dd53171d645bc011c84b5087244] [structERIS_ac372ad4cb17b18d0d3e2ce7bfe970fbc] [structERIS_aa2b057d6e96bd5f4ac3761d9e38689e6] [structERIS_af0200895dba3547c9ea882142cde9197] [structERIS_a816bef39acccbe0732a634827f00091d] [structERIS_a5a7dde7e5ee1b5e68dac70b3a09be745] [structERIS_a15b49effc03c39587df29a16b694242d] [structERIS_a781bf4cc6d4a8af62c7a391c16880979] [structERIS_a1e1caaacbead60ba2bdea30dff17e941] [structERIS_a9cbd69c7ad62832ffd8dcbe255f83d1d] [structERIS_ad0b4447c7045d936f229aee0941c359b] [structERIS_a6c5dbc5227880cb78f6e65c16060f4cb] [structERIS_a5e2e564b7b9cedf1072eafb786890a02] [structERIS_a7ec6d729be463c37f202f6e7a432cbac] [structERIS_a92b52d91f51bf4f211261dc41febaa37] [structERIS_aa56379b46025b8686dd12c0bd8b7145e] [structERIS_a33574ef5cfbce10c10eb83989c176e5f] [structERIS_a52a15839c5ff34a1ddb55730850e93e1] [structERIS_a304ff39c8ab4196a475377baf82f932f]
The documentation for this struct was generated from the following file:
<span>#include <math><</math>motor_controller_common.h<math>></math></span>
=== Public Attributes ===
double 7
double 7
double 6
double 3
double
double
double
=== Member Data Documentation ===
[structERIS__LQG_a8806d631415884c9d64f2d3e518dddde] [structERIS__LQG_ac21c150b49c2fff2adfb0e5057fcc2ab] [structERIS__LQG_a498c5ca3fc85ce54403bef61cf41c875] [structERIS__LQG_a4d7694c9811f751f00f26e4fe43a9cbe] [structERIS__LQG_af6e2db69256e4c6d1502a14e21cb835e] [structERIS__LQG_ac137a0205e4f5816eb7b03d860199165] [structERIS__LQG_ad13d5c23aeb1a3c23b186db27724ef3c]
The documentation for this struct was generated from the following file:
<span>#include <math><</math>motor_controller_common.h<math>></math></span>
=== Public Attributes ===
float
float
float
float
float
=== Member Data Documentation ===
[structfilter_a09a899b4383ada744678070d267949fb] [structfilter_a1b76e61c6be0159b055e6e653d12e464] [structfilter_aab2e9732f6e1fd3a570996479328a124] [structfilter_ae0db9676750bedeb2e90d845a6e7ebfe] [structfilter_ae9cc7c8691d84414aaf60252fe5a52ec]
The documentation for this struct was generated from the following file:
<span>#include <math><</math>key_bindings.h<math>></math></span>
=== Static Public Attributes ===
static const char = ’v’
static const char = ’b’
static const char = ’n’
static const char = ’2’
static const char = ’m’
static const char = 27
static const char = ’w’
static const char = ’s’
static const char = ’d’
static const char = ’a’
static const char = ’p’
static const char = ’y’
static const char = ’t’
static const char = ’i’
static const char = ’u’
static const char = ’e’
static const char = ’q’
static const char = ’7’
static const char = ’4’
static const char = ’8’
static const char = ’5’
static const char = ’7’
static const char = ’4’
static const char = ’8’
static const char = ’5’
static const char = ’9’
static const char = ’6’
static const char = ’i’
static const char = ’k’
static const char = ’o’
static const char = ’l’
static const char = ’1’
static const char = ’3’
=== Member Data Documentation ===
[classKeyBindings_aef90171b20d79ebc257f170181eaf890] [classKeyBindings_a58695bbfce90d6ffc0a84196d89b9960] [classKeyBindings_af826ec5e2054b40f1deb054e64ca0529] [classKeyBindings_a47c5ee2c44867d20c24f762d36e97f59] [classKeyBindings_aebaae84b4f4db7abdae29caaea528e8b] [classKeyBindings_a06d10f62d58db35f26c4e29f3465f657] [classKeyBindings_a5fd4a7111057bea6e2aa3514ca7e49d4] [classKeyBindings_aa221252e7c8c7dfbd6bf52cec6ff9efa] [classKeyBindings_a3536a06efd932f9f83c7b1401e62ac74] [classKeyBindings_a528caa743573e714305d2f326cdae482] [classKeyBindings_a0601b0f2f1c994b385ef9ff19b445541] [classKeyBindings_a3c4bb88bba2ea8f911fee2ec3e94b621] [classKeyBindings_a65d61f86eb4cce6c226c3a6d5040a5ce] [classKeyBindings_a94d0f20713e0122528f111ac6384a10a] [classKeyBindings_a6a8577243dd58679a919601817459a3d] [classKeyBindings_ac2ab34fa8f84c3e61dd691c85d4d6a9d] [classKeyBindings_ab5de5431af2bbec9beed76240b8e7210] [classKeyBindings_a2bde3f4c440aed4f1ec8004554c8bb6e] [classKeyBindings_a9406856a5b5bb0e59b65d9389abe1229] [classKeyBindings_a83941cf8641d93aa0792519298ea0119] [classKeyBindings_af5a66599d1eb2a203db566ce95f6d667] [classKeyBindings_a0f328dc9694c01262ca88aeaedcbe365] [classKeyBindings_a068e0ae5f38a66b981aa94f6f36db7b5] [classKeyBindings_a947cefad7da0002ef80f31c1bab4e25e] [classKeyBindings_af237d7d82eacdf495b9b9df6d7d1c19d] [classKeyBindings_aedde92ca55442a92af50c0732697cf8f] [classKeyBindings_adf03756ecc709d0f5b73f3b6e162bbda] [classKeyBindings_a126181719b0381e792f0aa3886654698] [classKeyBindings_ab98a06f6baa445e56e6b662adf2f5e54] [classKeyBindings_a118fbfad6a18c2b32204277077f77f67] [classKeyBindings_acff79176396fc2c9c65713c08d0cb36f] [classKeyBindings_a13ccf108959855740a39ee977984b09c] [classKeyBindings_a2cbbf6deb2943cff3496b6da55752c71]
The documentation for this class was generated from the following file:
<span>#include <math><</math>logger.h<math>></math></span>
=== Public Member Functions ===
<span>'''Logger Object Removal'''</span>
''[_amgrpef40c65612bb88d1b1d4e0d91e727cc2] Deleets logger object.''
Removes the logger object by freeing the resouces used by the object.
()
<span>'''Initialize Logger'''</span>
''[_amgrp3996112c3a768bbd5ae89716a6094e6a] Initialize te logger instance.''
Initializes the data logging by creating the log files. This is called during initialization.
<span>Returns</span> true if the log file s open false if the log file is closed
bool ()
=== Static Public Member Functions ===
<span>'''Logger Instance'''</span>
''[_amgrp90163ef8e72e8956084b6b4bd9b35af6] Gets the logger instance.''
Gets the singleton logger obect
<span>Returns</span> The logger object
static <math>\ast</math> ()
=== Private Member Functions ===
<span>'''Logger Object'''</span>
''[_amgrp79673e6bbe5de34f023f632dc03e3db4] Creates logger object.''
Creates a default object. It is private to prevent someone from destroying the current instance.
()
<span>'''Write Logger Header'''</span>
''[_amgrped625226a046a655e3d77605a871ab56] Writes the headder of the log data.''
Writes the pid constants to the top of the log file. Writes the column titles and units to the top of the log file.
void ()
=== Static Private Attributes ===
static <math>\ast</math> = 0
=== Stop Logging ===
Closes the log file.
Closes the log file.
std::fstream
bool
bool
bool
bool
bool
bool
bool
bool
bool
bool
<math>\ast</math>
<math>\ast</math>
<math>\ast</math>
void ()
void ()
=== Constructor & Destructor Documentation ===
[classLogger_abc41bfb031d896170c7675fa96a6b30c] [classLogger_acb668a9e186a25fbaad2e4af6d1ed00a]
=== Member Function Documentation ===
[classLogger_a1287de14553cab2d7fddb74a015cef63] [classLogger_a4a2c28f7530b31a50684bee08c30c30e] [classLogger_a05311a9baf7b23ac45f0fa1a6ce1bea2] Writes a line to the log file. This is called whenever we need to log something into the file [classLogger_a52afa60704b98d0b206fd8bc978d2b0e] [classLogger_a680ecd9a68a45c4203a7b0c03f45e74f]
=== Member Data Documentation ===
[classLogger_a3477ad7e31f05db92807692445a2670d] [classLogger_a0fbc31b87c926c9ecf885b0f1675b1fe] [classLogger_ab18889d6fdbe2e2df34fc5f1f9c8bb02] [classLogger_a1f27181977abeeaebe319e1b18fe4b6a] [classLogger_acaa5b8f112473512838b557124e199c9] [classLogger_a9cef2ee3fe1f8c107ad07399ab4dff4a] [classLogger_af7d961fb7fb4b33bf589133ce84261f0] [classLogger_af8be280252ca544b1c2456084ce734aa] [classLogger_ad33727570915401a4960afcb4fcc0116] [classLogger_a06cf172509e2448b2a2c03fd9a20cd0d] [classLogger_ae133c211974fcb334209f997e770d56d] [classLogger_a0fcdcc99336a9fd24fc5d24039ef5393] [classLogger_a88d258aef340bd59cc36b66ab392b420] [classLogger_ad61e110daff94c8c3d5d2c94afbc7322] [classLogger_a3537680ba9f19fe19e98193a60014406]
The documentation for this class was generated from the following files:
<span>#include <math><</math>motor_controller_common.h<math>></math></span>
=== Public Attributes ===
int
int
int
int
=== Member Data Documentation ===
[structmotor__control__manual__t_a8597d7c041893e079504242ac0b08c29] [structmotor__control__manual__t_aa7380bb84a6a6fee523aca85b5829c6e] [structmotor__control__manual__t_a72fcf12d4d5eca4ddb5ce536a27d1e18] [structmotor__control__manual__t_ae51a611a6ae54a081226f5960f55881a]
The documentation for this struct was generated from the following file:
<span>#include <math><</math>motor_controller_common.h<math>></math></span>
=== Public Attributes ===
int
int
int
=== Member Data Documentation ===
[structmotor__control__speed__t_ac869c864bab0a829fdb6e4979b5423d4] [structmotor__control__speed__t_abe11c48ec856b2c22d3874040743d1f5] [structmotor__control__speed__t_a17c66d80537c25ba0f0b91ee29aa441d]
The documentation for this struct was generated from the following file:
<span>#include <math><</math>motor_controller_common.h<math>></math></span>
=== Public Attributes ===
int
char
int
int
int
int
int
int
int
int
int
int
int
int
int
int
int
int
int
int
int
int
int
int
=== Member Data Documentation ===
[structmotor__t_a8c4107c79b1e8be0bb867acb43f24dc2] [structmotor__t_ad10cf8ef2464c3948b63692c638220ac] [structmotor__t_a2da217bcba52c9f7730f547ce7b2f954] [structmotor__t_ab04b0231cc3d35441b9a550f6b709f37] [structmotor__t_aabc2e81419bf510dca8acdd9fdfb5fee] [structmotor__t_aa9d803b1dbe3ccc53502f498c67d0efd] [structmotor__t_a0b45561b3bd10d3fa5b967f27cc03b4d] [structmotor__t_a27a28d0b9cfa3d4df077d1b83b1ae50c] [structmotor__t_aa5e61f82d30c5beb67c3e4da63d3f973] [structmotor__t_a508cc8ca9efb12f6b7a2ca90c0145be3] [structmotor__t_ad9e0dad6c84f60b620b5c304f77a754e] [structmotor__t_ae1fd3fa15d93ee7ca77155e5065f19ae] [structmotor__t_a5aa7ba39f596fb84bc48ebe8bdf8742f] [structmotor__t_aa5663d6deb3ba03853ea1db9fee6d77a] [structmotor__t_af7acea56015c47320ad037a6447267a3] [structmotor__t_a01421ca52664b63fe5cf9045b31b5a93] [structmotor__t_af9f663b6c75e472266caa35a7327c7d9] [structmotor__t_a33267a8129db0fa1294a1e8411507b56] [structmotor__t_a228fe22eb14566279ab42ef21c8a056b] [structmotor__t_a7e8adeb92e7b56bec55778e93188b5ac] [structmotor__t_a633626a1a87f7660c37cfee774da143e] [structmotor__t_aef378823f8f766d89f79a12c1fad7298] [structmotor__t_afa5290085f6f4cbb82321b61f0e759e2] [structmotor__t_aa8f2bb71f13d25bd493f086b25d2a793] [structmotor__t_ab2e32b36075436b3d3022c2d08c6c7af]
The documentation for this struct was generated from the following file:
<span>#include <math><</math>motor_controller.h<math>></math></span>
=== Public Member Functions ===
<span>'''Initialize all Quad Motors'''</span>
''[_amgrpfce05aebd28fd6a36058c581a4d953d3] Initializes all four quad motors''
Uses the initQuadMotor to initialize all quad motors.
void ()
<span>'''Initialize Quad Motor'''</span>
''[_amgrp1d644151bbcce9057e75fa35a143c31a] Intializes a specific propeller motor.''
The propeller motor is is initialized in open loop tapaziodal profile on the FPGA PWM generator.
void (int motorNum)
<span>'''Set Qaud Duty Cycle'''</span>
''[_amgrpf05c4be638915bb1f32e0410817774b6] Sets the quad motor duty cycle of a single quad motor.''
Sets the desired PWM generator block C to the desired duty cycle.
<span>Parameters</span>
is the desired PWM command
is the intiger value for the motor number in the PWM generator C block.
void (int pwmgen_value, int motor_num)
<span>'''PID Control Calculator'''</span>
''[_amgrp9957f7bb2056d8a6c35ddf4083298f7b] Calculates the output of a PID controller.''
Runs a PID control algorithm on the struct. Doesn’t saturate the PID correction.
<span>Parameters</span>
A pointer to a struct
<span>Returns</span> the controller output as a double
double ( <math>\ast</math>pidptr)
<span>'''PID Control Calculator with Filtering'''</span>
''[_amgrp14c8571050a8ae6f680e516dc4f4e5ac] Calculates the output of a PID controller with filtering.''
Runs a PID control algorithm on the struct. Doesn’t saturate the PID correction. Filtering is used in the derivative calcuation.
<span>Parameters</span>
A pointer to a struct
<span>Returns</span> the controller output as a double
double ( <math>\ast</math>pidptr)
<span>'''Load Motor Controller Configuration'''</span>
''[_amgrp5f023cd0ca8b5dab8a80d84aba4ef6c6] Loads configuration data and initializes some controllers.''
Initializes controllers and filters needed for controller calculations. It reads in data from eris.cfg and other hard coded values.
<span>Returns</span> 1 if sucessful
int ()
<span>'''Arm Quad Motors'''</span>
''[_amgrp5c2ef70f6e4cadb7e720b01879f688a3] The quad motor ESC require an initialization sequence, this function creats that sequence.''
The ESC comands a cycled through a set of values to activate the ESCs.
void ()
<span>'''Data Filter'''</span>
''[_amgrpd7dc50ca0736a594701687e8186067ab] Filter a data set using an FIR digital .''
Calcualtes an FIR used to data in the time domain.
<span>Parameters</span>
The point to the object to use
The input data to the
The output
float (struct <math>\ast</math>, float data)
<span>'''State Feedback Controller Calculator for 1D inverted pendulum'''</span>
''[_amgrp0537bb25e7f514750bffba69f7f4dba0] Calcuats the pole plavement controller for RADA''
Using the a (quad state space) struction it calcuates the controller output. This is for a 1D inverted pendulum.
<span>Parameters</span>
is a pointer to the structure to be used to calcualte the controller output.
the contoller output as a double
double ( <math>\ast</math>ssptr)
<span>'''State Feedback Integral Controller Calculator for 1D inverted pendulum'''</span>
''[_amgrpf03ca3c2efc11db8bbd67d4f5cc8746c] Calcuats the pole plavement controller for RADA''
Using the a (quad state space with integration) struction it calcuates the controller output. This is for a 1D inverted pendulum.
<span>Parameters</span>
is a pointer to the structure to be used to calcualte the controller output.
the contoller output as a double
double ( <math>\ast</math>ssptr)
<span>'''RADA LQI Controller Calcuator'''</span>
''[_amgrp078731063da6706b78f325db9a9695df] Calculates the LQI controller output with estimation.''
Filter the angular postion, calcuatetheangularrates, and then calcualte the controller outputs for the whole RADA system.
<span>Parameters</span>
is a pointer to the LQI controller structure
<span>Returns</span> 1 as long as the controller is calculated
int ( <math>\ast</math>lqiptr)
<span>'''State Space Control Calculator'''</span>
''[_amgrpf6257f816f8d6d1766ce1561b15f352f] Caculatesthe state space controller (controller and estimator) comands.''
Calculate the controller output based off of the previous estimation and then estimate then ext step of the controller.
<span>Parameters</span>
is the pointer to the state space controller object
<span>Returns</span> 1 if the controller calcultes the controller
int ( <math>\ast</math>ctrlss)
<span>'''State Space Controlelr Configuration'''</span>
''[_amgrpd94fd80ab4422727a101b6dc5baeb94a] Initializes a state space controller.''
This function initializes as state space controller (H2) that can track references or Dance depending on complier macros.
1 when the initialization is complete
int ()
<span>'''MSP Packet Drop Controller Calculator'''</span>
''[_amgrpdef89e6ca047cb84488107cf20260329] Calcultes the MSP controlelr for lossy systems.''
Calcutes the value v2 (a set of inputs). Then calculate u2, a set ouf outputs. Next calculatev1_bar a set of inputs. Then calculate u1 a set of outputs. Then calculate Yo the scaled outputs that are sent to the actuators. Next calculate estimation of the next time step’s state. Finally, set these next step etimated states to thecurrent state estimation.
<span>Parameters</span>
is a pointer to the packet loss controller structure
<span>Returns</span> 1 when the calculation completes
int ( <math>\ast</math>ctrlss)
<span>'''State Space Controller Configure for Packet Loss'''</span>
''[_amgrp37c81e75a7a9d084c58c456e7571158e] Configurs the Packet drop controller.''
Configures the initial state estimation, inputs, and outputs.
<span>Returns</span> 1 when the controller structre is initialized
int ()
<span>'''PID Control Calculator with Filtering and Variable Time Step'''</span>
''[_amgrp063a8faceb5db6e16b76dbd036348387] Calculates the output of a PID controller with filtering and time step calcuation.''
Runs a PID control algorithm on the struct. Doesn’t saturate the PID correction. Filtering is used in the derivative calcuation and calculating theactual time between controller calculations.
<span>Parameters</span>
A pointer to a struct
The time between the last sample and now as a double
<span>Returns</span> the controller output as a double
double ( <math>\ast</math>pidptr, double dt)
<span>'''RADA LQI Controller Calcuator with Variable Time'''</span>
''[_amgrpbcc1a735d18c2d59c7f5d9a769ad357e] Calculates the LQI controller output with estimation using theactual system dealt T.''
Filter the angular postion, calcuatetheangularrates, and then calcualte the controller outputs for the whole RADA system.
<span>Parameters</span>
is a pointer to the LQI controller structure
is a double that is the time between samples
<span>Returns</span> 1 as long as the controller is calculated
int ( <math>\ast</math>lqiptr, double dt)
<span>'''RADA LQI Controlelr with Estimator Calcuator'''</span>
''[_amgrp7500c88d96ef8d92553589505462fd1c] Calculates the LQI controller output with normal estimation.''
Calcualtes the controller output, estimate the next time step’s states. Set the current states to the next states.
<span>Parameters</span>
is a pointer to the LQI controller structure
<span>Returns</span> 1 as long as the controller is calculated
int ( <math>\ast</math>lqiptr)
<span>'''LQG Controller Calculator'''</span>
''[_amgrp41ce89edf82c1d5162ec0a37eeb4a94a] Calculatesthe LQG controller for the whole RADA system.''
Calcultes the controller outputs using the previous time step’s estimation and the current inputs. Then it estimates the statesof the next time step.
<span>Parameters</span>
is the pointer to the LQG controller structure.
<span>Returns</span> 1 once the calcution is complete
int ( <math>\ast</math>ctrlss)
<span>'''LQG Quad Controller Calculator'''</span>
''[_amgrp829e83dc64015e37961d2d115748c72e] Calculatesthe LQG controller for the whole pendulum system.''
Calcultes the controller outputs using the previous time step’s estimation and the current inputs. Then it estimates the statesof the next time step.
<span>Parameters</span>
is the pointer to the quad LQG controller structure.
<span>Returns</span> 1 once the calcution is complete
int ( <math>\ast</math>ctrlss)
<span>'''LQG Eris Controller Calculator'''</span>
''[_amgrpc38c2a17da2f8813651939769b09ec53] Calculatesthe LQG controller for the whole Eris system.''
Calcultes the controller outputs using the previous time step’s estimation and the current inputs. Then it estimates the statesof the next time step.
<span>Parameters</span>
is the pointer to the eris LQG controller structure.
<span>Returns</span> 1 once the calcution is complete
int ( <math>\ast</math>ctrlss)
<span>'''Initialize Motor Contorllers'''</span>
''[_amgrpd1997c79c23a3862511f6af22c0ec5da] This funtion initializes the motor controller strucures.''
Initializes the . If the mode is anything other than free, then the controller will attempt to acquire the motor device descriptors as defined in the Configuration object.
<span>Returns</span> 1 on success, 0 otherwise
int ()
void ()
<span>'''Stop Motors'''</span>
''[_amgrp3ef1bdab6ae253ecc163a825f4ea9e9f] Stops all motors.''
This will stop all quad and ground robot motors
void ()
<span>'''Stop Ground Robot'''</span>
''[_amgrp5ca3b6a80bff934023e8810a002438b4] Stops all wheels.''
This will stop all ground robot motors. This is different from because the controller will still maintain the connection to the motor device descriptors, but the motors will be stopped.
void ()
<span>'''Set Motors'''</span>
''[_amgrpdadd3c7c8f5910982d289bd98101684d] Sets the speed of the wheel motors.''
This will control the motors in a manual way, such that each motor can be controlled individually.
<span>Parameters</span>
The parameters for the movement command.
void ()
void (const struct <math>\ast</math>command)
void (const struct <math>\ast</math>command)
void (float dt)
void (MotorControl <math>\ast</math>packet)
void ()
void ()
int ()
int ()
void (int useBoundsLimit)
void (int useStatusLogging)
=== Private Member Functions ===
<span>'''Motor Controller default object'''</span>
''[_amgrp9e5257757bb47d5223c038f91d3ca39b] Creates a motor contorller object.''
Creates the object. Nothing is requested of the motor controller board at this ponint.
()
<span>'''Free Motor Controller bject'''</span>
''[_amgrp407b092ba9c174a55708b5d3e7ba1e6a] Deletes the motor contolelr object.''
Frees any resources used by the motor controller.
()
<span>'''Initialize One Wheel Motor'''</span>
''[_amgrpf5dc760419735c025a71fd62d74cb75f] Initializes one of the motot settings on the MESA board.''
Initializes one motor
<span>Parameters</span>
The motor structure to initialize
void (struct &motor)
<span>'''Initialize All Wheel Motors'''</span>
''[_amgrp624dc6c5d4b272edbe3b43cae3f7e0ee] Initializes all wheels.''
Initializes all the motors
void ()
=== Static Private Attributes ===
static <math>\ast</math> = NULL
=== Motor Controller instance ===
Get the instance of the motor controller.
Returns a single instance of the .
<span>Returns</span> A single instance of the
struct
struct
char
char
short
short
short
short
int
int
struct
struct
struct
<math>\ast</math>
<math>\ast</math>
static <math>\ast</math> ()
=== Set Motor Speeds ===
Passes the motor speed settings to the FPGA.
Passes the motor speeds onto the motor board. After this command has been executed, the robot will begin to move.
class
class
void (const char <math>\ast</math>name, const &motor)
void ()
static int (unsigned int degree)
static int (unsigned int degree)
=== Constructor & Destructor Documentation ===
[classMotorController_a1c32db157ba4b6dba1f2d6bc8891f16d] [classMotorController_ae4a6055b64466936c3576fb52fda9307]
=== Member Function Documentation ===
[classMotorController_add1bf5dae0eb05623df4b754d1c6fb49] [classMotorController_a93e60b0fa743ec1a6a69957d64689b55] Computes the output of cos(degree)<math>\ast</math>256 using a lookup table
<span>Returns</span> (int)(cos(degree)<math>\ast</math>256
[classMotorController_a2553c87383d8241316ea2053fb12c7a4] [classMotorController_a48e1b88df6b0d6da8195ba102108d9d9] [classMotorController_a34520b22e1f3e4a6529133fb2481d32e] Gets if the motor controller is using bounds limiting
<span>Returns</span> 1, if the korebot stops the motors when it leaves the bounds of the playing field, 0 otherwise
[classMotorController_af3bade74d928cdddf29dbcaec33e9dba] Gets if the motor controller is logging status
<span>Returns</span> 1, if the motor controller is logging, 0 otherwise
[classMotorController_a4fecad722d049d29bc6efc6b4a549048] [classMotorController_a7e93f0790d37d266359cab27eaf19389] [classMotorController_a1772b5eb25ed867b6799c6488a1da283] [classMotorController_a6ea32666e8808436dc6d299a26e96d08] [classMotorController_a41163916eb76f85ea6d5c0bfeb0b0869] [classMotorController_ace062a26702f28230668809781e41039] [classMotorController_a712bfbc418522a2297053b16cd04ba3d] [classMotorController_a953b0bd7cf69a499d444e283cdcf2c6f] [classMotorController_a9b9cf813441e188fec5dde9783e4a56f] [classMotorController_ab64a7f9780e66317a624cdd945070b80] [classMotorController_a69d031076349d49d2a68de9d7a8ca8db] [classMotorController_a0b1e833f2acca5f4ca229edcdb982ba1] Prints the status of the given motor to console
<span>Parameters</span>
A human-readable description of the motor
The motor details
Prints the status of the given motor to console
<span>Parameters</span>
A human-readable description of the motor
The motor details
[classMotorController_ae350b355b22cd83ad7b735e456b146a9] Prints the status of various modules on the Korebot [classMotorController_a419d79a3fff2307b0ab96418270cbf92] Processes a packet received over the network
<span>Parameters</span>
The packet received from the network
[classMotorController_a0e32982f7d58fc52a0bafe4f50572faa] [classMotorController_ad90235c67d1e809452589cba4b58f806] [classMotorController_a96915dcda6bfca14d18e523542982d49] [classMotorController_a2282991fb80e1689e1e7ffaa104015f2] [classMotorController_a0265a0be71190b23bdb591cde9c68097] Runs one iteration of the motor controller; Sets the speeds of the motors according to how the user / AI wants them to go.
<span>Parameters</span>
The time difference since the last call to this method
[classMotorController_addb10f30dae3f4daeb0074b28f0ee1d1] Sends status information about the sensor manager to the control server.
This includes the mode & speeds of the motors. [classMotorController_a2e5e8ac28229cb8f9a0ce5f64a8d5b77] [classMotorController_a5abb6d80f4891452cbb6a3c7a3c32d5c] [classMotorController_a65dfcc468ce3529defe398fe7bf7392d] [classMotorController_ac9bd97a93cbe94bf844e80ef23056ad6] [classMotorController_a25f60534f1ef27d30f6cdf62519c791a] [classMotorController_a4e45155b4d2d208dc76967c304b7ebf3] Sets if the motor controller should stop the motors if the korebot leaves the bounds of the playing field
<span>Parameters</span>
1, if the korebot should stay in-bounds, 0 otherwise
[classMotorController_ab76a224b0d5188d15f33b6b697905933] Sets if the motor controller should log the status information to a file
<span>Parameters</span>
1, if the motor controller should log, 0 otherwise
[classMotorController_a41bec40abfaefa050d98ea4522945bd6] Shuts the motor controller down, destroying any resources & releasing any devices the controller is holding. [classMotorController_a4635621e96ad618a1f33d02165cdfc9e] Computes the output of sin(degree)<math>\ast</math>256 using a lookup table
<span>Returns</span> (int)(sin(degree)<math>\ast</math>256
[classMotorController_a50e55a6199c3cef74b5e8cd64039f315] [classMotorController_a69733631dbe8550b52933cc03fcb0f54] [classMotorController_aab0247df4f0413a46e68ada1e3b4e991] [classMotorController_a3b1f06b4d39a840887079ce725401162] [classMotorController_a46b269cc3a363a8a621e3f50aef79963] [classMotorController_af0e455864d2af2f4f293961d95b843a1] [classMotorController_a317ce58ea93ea1329de5b87391560082] [classMotorController_a1296842f7e49211c6dd36023967e8ac2]
=== Friends And Related Function Documentation ===
[classMotorController_a0191eec9042e10ff1da22f98f14498fb] [classMotorController_a56b5005fdfe78e27f0ecd4d7d876b646]
=== Member Data Documentation ===
[classMotorController_a1d97bedd5ac33c60ecb00442569b0ada] [classMotorController_a746ddd1d96190bbc14669d555ae1ed11] [classMotorController_af9ad9c5897f6fc801694837c2ecce6e5] [classMotorController_ab78c465d4e96d3c8b21b08fa8b2f5589] [classMotorController_a915f7c7db7eafe922c183f0a008ae53a] [classMotorController_a07e3f68c416a983de11e401b5c0f1433] [classMotorController_a77bd609c9cce4b00533f00eb3b4b9197] [classMotorController_ac14cc62eae3a30fc2752a78fbd18a6e8] [classMotorController_ad49cd20423752fe17d45abca19fcd5f8] [classMotorController_aa53faa6f4491dcdc8fbcaa22ca0498d5] [classMotorController_a7dfcbab99afde391b774d444f603fb5b] [classMotorController_a12e46cfc455ac7e814a977d244be5f08] [classMotorController_a824e25371c790d050dc68a8ca861ac17] [classMotorController_ac455cbf551bd87ff0e7b9647d3e29caa] [classMotorController_a1d266c8a0c0bd8d1a123fe92eadac4b4] [classMotorController_a34ba46e538027b3897d8a52c432acea8]
The documentation for this class was generated from the following files:
<span>#include <math><</math>motor_controller_common.h<math>></math></span>
=== Public Attributes ===
struct
struct
struct
struct
=== Member Data Documentation ===
[structmotortrain__t_ac93c32e936810c89d906a780388fa543] [structmotortrain__t_a936dab25cd19cd882c1f4b5547f6854d] [structmotortrain__t_a0975c7dc29c06eb3e41c7b3d2d89f897] [structmotortrain__t_a7374ec1fab1a3b24ab05f4f3f562286a] [structmotortrain__t_a17d91b9941dd97fe08ac5f05d320db77] [structmotortrain__t_a1bf8fd344ea4ab736e8be74807f28ce8] [structmotortrain__t_aa512d3487dad0e44ba34f7bd80644989]
The documentation for this struct was generated from the following file:
<span>#include <math><</math>motor_controller_common.h<math>></math></span>
=== Public Attributes ===
double
double
double
double
double
double
int
int
int
int
double
double
double
double
struct
struct
struct
int
int
=== Member Data Documentation ===
[structQUAD_a2eed9f1713c43f7c7491813afe60d159] [structQUAD_a00d9ad43243a8079bdafc17bad61e8a8] [structQUAD_a10e64234abe44400db28b86cccf71b9c] [structQUAD_a37a8faccecc87a0a36db7758aebd4cd3] [structQUAD_ab6322c69c61e8c52113215b8782f5640] [structQUAD_a1c0d275153c7e8f6a96cb438c57de6fb] [structQUAD_a8e0ab0fca05fa4368e9c142b879165b8] [structQUAD_aae593162318a8f85cee245d36384e43e] [structQUAD_a8fb550e3a46fca686af955f7070891d5] [structQUAD_aa39e1ed5847afe259a4bed63fdcdcdb2] [structQUAD_af0a105f1ee7eb97eab0db1b5e1996f37] [structQUAD_a1e4d41cb80153a8d7cd81c66c98c8b3a] [structQUAD_adefa68d6df6fb3288bce229cad63eaa3] [structQUAD_a2f1b6a7383290f5c552eef5e51825a35] [structQUAD_ae9bb78262875c8a49b7c1ce6eba1691f] [structQUAD_a5d6a99d953ddbc2f0e0d799459afbe0b] [structQUAD_a893e505f05bad2f5904387c926f12c8c] [structQUAD_a5f2425f4d2370d30a963157527e2bf9c] [structQUAD_ae7f289e91404a2f165d2f7c6a25a8450] [structQUAD_aa8a9da65a487c47e81c77b33323428ef] [structQUAD_ae2c9ab465e6ebfe2a26122cc3caf15d7] [structQUAD_a17071969d4bc2093b3d2fc1ee83af04d] [structQUAD_a5150d2569d431a1380cb7d837e96ebf5] [structQUAD_ace794fbc91c3193f6e5e42d1f8e2cd64] [structQUAD_a754e8f9b57794e2ab9b4c3542e39464d] [structQUAD_a79b59140f8b04dac9218dcc699f5b3f8] [structQUAD_a2449ef626bfeca6b8a7c63fcbc2c6818] [structQUAD_a542aee3387201368593832b4e47ba743] [structQUAD_a883c6b66339a648916033d296368f9dc] [structQUAD_aedc6dc7e5aa35ef51d1ced2dce9513a0] [structQUAD_a2ab750ab10497d939cdddba72cfc4de6]
The documentation for this struct was generated from the following file:
<span>#include <math><</math>motor_controller_common.h<math>></math></span>
=== Public Attributes ===
double 6
double 6
double 4
double 2
double
double
=== Member Data Documentation ===
[structQUAD__LQG_a76bbbb078df43082bbd27354d9458b9d] [structQUAD__LQG_ae06b105072a09fdfe8bf26f6db82e1d3] [structQUAD__LQG_a34c2cd67f46354f4dd1390ceb13d8639] [structQUAD__LQG_ab2510335708e94ce453625ec6c88a8f4] [structQUAD__LQG_a45f38782147369b8b6df1999ebdcfa17] [structQUAD__LQG_ac031b1e1bb3c1e293c422eb66f388f39]
The documentation for this struct was generated from the following file:
<span>#include <math><</math>motor_controller_common.h<math>></math></span>
=== Public Attributes ===
double
double
double
double
double
double
double
double
double
double
double
double
double
double
double
double
double
double
double
double
double
=== Member Data Documentation ===
[structQUADPID_af57693675d3b91e74c7fce833c2d3229] [structQUADPID_a37120d7ed179891e570632dde992a62d] [structQUADPID_aebe069933b736158b6e9c66480b5dd66] [structQUADPID_a9e340ef1ec326c3ea24ab853eaab5356] [structQUADPID_a8c459e89dad8aba573f629a2eee95a2e] [structQUADPID_a53abc22b47daebd646ffa93edeebabf3] [structQUADPID_a15a2c22f71f430b0f3da088fdaf11e8b] [structQUADPID_a35bd258abd8b446cf0fc7192f5444ace] [structQUADPID_aad48c2639f5e7f7a7507a65f2fc9f840] [structQUADPID_af0c37cfc4dd8de23ea8e1f5a9dde49ca] [structQUADPID_ac0ca662a0fd18d9a7ae9be60f16642aa] [structQUADPID_a4e96ee985a438bbac5a5a2e7c20a6ba3] [structQUADPID_ac2322202d22bfef5a2bac06ab69ad04e] [structQUADPID_adffd1a7f278135c8b1dbe8ed3c028d49] [structQUADPID_a641e3400a556ef67ae641bb748f35502] [structQUADPID_a37ec2314c8e6ea28ce2bf9677bac90c3] [structQUADPID_ae2363c0b0775bd8139ba5768470b986d] [structQUADPID_a074e9f874f299cd53447a34638c0daad] [structQUADPID_ad2e9f72912b4f53ec0a6c57652706a9f] [structQUADPID_a5b2c0619378b80766a76fe248d4e82cf] [structQUADPID_a52b5fb6398fecd60c22bedd8b5c88554]
The documentation for this struct was generated from the following file:
<span>#include <math><</math>motor_controller_common.h<math>></math></span>
=== Public Attributes ===
double
double
double
double
double
double
double
double
=== Member Data Documentation ===
[structQUADSS_add3c0c29d0b5a86bc0650e10048da943] [structQUADSS_aea9e3c78961e8d18c5a5b0e7801a3757] [structQUADSS_a429e966bc34c1bdc2277139488b777d6] [structQUADSS_aedab9a84e7fe0fc90e9fb6573f92edc9] [structQUADSS_a82100cd859c1d02e9a0610610f9ce598] [structQUADSS_a848a1f6b9b1386b06cbc1545a8a850bf] [structQUADSS_a5184771429743ed0518c4cb93764bdc1] [structQUADSS_a4586121326628ddd1183bb6bf7bbcf39]
The documentation for this struct was generated from the following file:
<span>#include <math><</math>motor_controller_common.h<math>></math></span>
=== Public Attributes ===
double
double
double
double
double
double
double
double
double
double
double
=== Member Data Documentation ===
[structQUADSSI_a578f581dca979d890f092a5276c1de2e] [structQUADSSI_a4226d40c10573f3f827ae7666ef1fc44] [structQUADSSI_a9abfe43101a30f54fe2d38d60de74b2c] [structQUADSSI_a2c5a14aeaeee20b7f0a28f519bb88ba3] [structQUADSSI_ac85d5d5297bdae061cafd99d3a1735c5] [structQUADSSI_a16756c462227bebb2eada031f7926249] [structQUADSSI_adbc07d19432895cd041db18a418ed9ac] [structQUADSSI_a474e0b411cc0f122694e51d1b0659acf] [structQUADSSI_abece16790d7a4e8a8ca59afb9448c370] [structQUADSSI_a45e12800b609b4a4f8b3bac4566695cc] [structQUADSSI_a4a270033dec1ba6e9339ae6165389c9f]
The documentation for this struct was generated from the following file:
<span>#include <math><</math>motor_controller_common.h<math>></math></span>
=== Public Attributes ===
double 13
double 13
double 10
double 5
=== Member Data Documentation ===
[structRADALQG_aa940eeca8f5baac2249898725297a0d0] [structRADALQG_af266d468cac40fa2d420f8bfddd7b557] [structRADALQG_ae3d7654593c0ce69332c8a60ea4cb4b7] [structRADALQG_a71dff35bb7444784fa6a4fb0abfd79e6]
The documentation for this struct was generated from the following file:
<span>#include <math><</math>motor_controller_common.h<math>></math></span>
=== Public Attributes ===
double
double
double
double
double
double
double
double
double
double
double
double
double
double 8
double 8
double 5
double 513
double 5
double
double
double
double
double
double
double
double
double
double
double
double
double
double
double
double
double
=== Member Data Documentation ===
[structRADALQI_afdcf53ebe9bcecebb6672e3477bf3033] [structRADALQI_a951609272a5a9521d530b01e9ef09595] [structRADALQI_a3db98fefec3bacd77109ed872770ee52] [structRADALQI_a5c8328044c5e72bd14586d7518597d86] [structRADALQI_a03256a0ae4e91b1be17aff1e5fe5d97e] [structRADALQI_a187690a16632205e125a65ad4c446eb0] [structRADALQI_a923333c98a36453319870d2c3c41e664] [structRADALQI_a7553fcb3e6b678243cb011c35b8f7654] [structRADALQI_aa922b81415119cbcc3bc2cda233187aa] [structRADALQI_ac7c14eccdd17f87c18fc0d3c5a9fbeff] [structRADALQI_a6da18a4d7a2ce4036df91f6dadff1046] [structRADALQI_a4a8c3336e535d69214c5b1544cff8a4f] [structRADALQI_a029c912330265d6601207a31b673ac2e] [structRADALQI_ab8db739fd43babe83c86aaccdee03107] [structRADALQI_ac3ba42e78de0c7a9f9bac06ee59d9af7] [structRADALQI_a38be3a08ecdef8905bf026197ec2d001] [structRADALQI_a00e509effa31ce836d84e8ac44691237] [structRADALQI_a5f04861fdd822873fddfbb9b8ed6e1ac] [structRADALQI_a295076da380631add54edc56a0720cf1] [structRADALQI_a2ac030254978e192ed3a511324dd5dc6] [structRADALQI_a9e3250b14c3c011c300dff35b7358558] [structRADALQI_ad58dffb99676bd9adb92bc5af8bb1c70] [structRADALQI_a7b2374ca0e9ccfeb1beb1d272b39b0b4] [structRADALQI_aef3f073773528798287820fd58976d14] [structRADALQI_a97aa272c346c35631ca4564a37124dc5] [structRADALQI_a229c3294975da8be631e9e11107c37af] [structRADALQI_a8d61dd4ba5cd4475c5146bd11b467a9b] [structRADALQI_a15fb171c13f71768f9919b8f1f691dd3] [structRADALQI_a48be324b5e318ac948cc745350b2d234] [structRADALQI_adafde08ed92f42256ca80f4c62d61614] [structRADALQI_a2885d192d345fbc7b2032b3ddaf6adfd] [structRADALQI_a469a7e328410a7a783338c6609d8cc06] [structRADALQI_aa93908270a2fa6ab0e608ce60c68f47f] [structRADALQI_acdc45aaafc81cd9d721e7fcb8eecb746] [structRADALQI_a99de43ecd01f525e3c3e25c61a81d842]
The documentation for this struct was generated from the following file:
<span>#include <math><</math>vrpn.h<math>></math></span>
=== Public Attributes ===
double
float
float
float
float
float
float
=== Member Data Documentation ===
[structvrpn__data__t_a36832473aff982b334e73ef8f2107975] [structvrpn__data__t_a174930b2f9de89327cbd168ecc288da2] [structvrpn__data__t_aef6531470caa7a95e650b19ed0139ae6] [structvrpn__data__t_a5a5a96aa9d0640599eb1d950e8e4c833] [structvrpn__data__t_a5faf10d13f8203d5d34ed0ac580d50ee] [structvrpn__data__t_a643aa072522e303a9d9cd7637d8632a0] [structvrpn__data__t_a9b71e15122a1d3fa495f5e6a797c7084]
The documentation for this struct was generated from the following file:
= File Documentation =
This clss dercribes the key bindings for the UI.
=== Classes ===
class
=== Detailed Description ===
This clss dercribes the key bindings for the UI.
<span>Author</span> Dylan Gransee, Robert Larsen
<span>Date</span> July, 2016 This class holds the key bindings for the command line interface. Changes and additions can easily be made by anyone who does not like the available commands.
The different sets may have the same command because you can only use one set of commands at once.
Code that logs data from RADA system tests. <span>#include <math><</math>iomanip<math>></math></span>
<span>#include ‘"logger.h‘"</span>
<span>#include <math><</math>iostream<math>></math></span>
<span>#include <math><</math>string<math>></math></span>
<span>#include <math><</math>sys/stat.h<math>></math></span>
<span>#include ‘"utils.h‘"</span>
=== Variables ===
struct
const string = ‘"<math>\backslash</math>033H<math>\backslash</math>033J‘"
=== Detailed Description ===
Code that logs data from RADA system tests.
<span>Author</span> Paul Uhing, Ian McInerney, Dylan Gransee, Robert Larsen
<span>Date</span> July, 2016 This file logs data to a text file in the Eris directory /root/Logs/ErisDate/log(timestamp).txt There are some compiler macros for configuring the logger. They must be set in Logger.cpp because Paul Uhing couldn’t get the macros in to work in . . ssDrop makes the logger log data for the MSP packet drop controller. RADAlqi_est causes the lager to log controller inforamtion about a LQI controller . RADAlqi_est causes the lager to log controller inforamtion about a LQI controller with a traditional estimator. rada_lqg causes the logger to log data about the LQG controller for the whole system. rada_split_lqg causes logger to log data about the seperate LQG controllers. rada_split_lqg_ol causes the logger to log data about a LQG controller and the Eris to control its yaw with a PID and the linear velocities are controlled through open-loop commands. H2ctrl cause the logger to log data about a H2 controller. If ssDrop, H2ctrl, RADAlqi, RADAlqi_est, rada_lqg, rada_split_lqg, or rada_split_lqg_ol are not defined then RADA will default to PID control.
=== Variable Documentation ===
[logger_8cpp_ae565de10fdcd13a32c3deef98b10b045] [logger_8cpp_a57e5a12456f314ffc728d5d8da312970]
<span>#include <math><</math>fstream<math>></math></span>
<span>#include ‘"motor_controller.h‘"</span>
=== Classes ===
class
main code that controls the data flow for running RADA <span>#include <math><</math>iomanip<math>></math></span>
<span>#include <math><</math>iostream<math>></math></span>
<span>#include <math><</math>string<math>></math></span>
<span>#include <math><</math>cstdlib<math>></math></span>
<span>#include <math><</math>cstdio<math>></math></span>
<span>#include <math><</math>pthread.h<math>></math></span>
<span>#include <math><</math>quat.h<math>></math></span>
<span>#include <math><</math>signal.h<math>></math></span>
<span>#include <math><</math>ctime<math>></math></span>
<span>#include ‘"configuration.h‘"</span>
<span>#include ‘"korebot.h‘"</span>
<span>#include ‘"logger.h‘"</span>
<span>#include ‘"motor_controller.h‘"</span>
<span>#include ‘"utils.h‘"</span>
<span>#include ‘"vrpn.h‘"</span>
<span>#include ‘"key_bindings.h‘"</span>
<span>#include ‘"sensor_manager.h‘"</span>
<span>#include ‘"sensor_manager_common.h‘"</span>
<span>#include <math><</math>math.h<math>></math></span>
=== Defines ===
#define
#define 26000
#define 56000
#define 65535
#define ((DUTY_CYCLE_MAX - DUTY_CYCLE_MIN) / 2) + DUTY_CYCLE_MIN
#define (DUTY_CYCLE_MAX - DUTY_CYCLE_MIN) / 2
#define 6656
#define 26880
=== Enumerations ===
enum { , }
enum { , , , }
=== Functions ===
<span>'''Handle pendulum postion VRPN callback'''</span>
''[_amgrp37d875ee3807f019e19d2d6dee41a566] Preocesses the pendulum VRPN data.''
vrpn callback function that is called everytime vrpn data of the pendulum is received. The callback gets the data and calls the pid controller by passing that data in.
<span>Parameters</span>
no clue what this is
the vrpn data that was received
void VRPN_CALLBACK (void <math>\ast</math>, const vrpn_TRACKERCB t)
<span>'''Handle Eris VRPN callback'''</span>
''[_amgrpe6e20aba9f601fcbc946d140a2025da7] Processes the camera system data for Eris from VRPN.''
vrpn callback function that is called everytime vrpn data of Eris is received. The callback gets the data and calls the pid controller by passing that data in.
<span>Parameters</span>
no clue what this is
the vrpn data that was received
void VRPN_CALLBACK (void <math>\ast</math>, const vrpn_TRACKERCB t)
<span>'''Main thread UI control'''</span>
''[_amgrpf3df38af8777b52967885581a6bf5072] Handels the user input and data printed for the user.''
This thread prints of data to the user and checks for user input the changes control modes and references. In the Stopped mode the thread is looking for the user to request entry in to the other modes or exit the program. It also stops the VRPN thread from executing. In tuning mode the user will be allowed to tune the pendulum PIDs. In Robot control mode the user can give commands to manuver Eris. In Box step mode the pendulum goes through a series of setpoint steps. The escape key will cause the program to stop.
<span>Parameters</span>
is a pointer to the thread ID of theis thread.
void <math>\ast</math> (void <math>\ast</math>threadID)
<span>'''Control Loop Thread'''</span>
''[_amgrp4e6e712710141b9bb1acc2a64aef0639] The main function for the control loop thread.''
This thread should be used if the packet drop code is ever edited to work with a real fading network. It should be implimented such that the controller will run every 10ms and determine if there has been packet loss
<span>Parameters</span>
is the thread ID
void <math>\ast</math> (void <math>\ast</math>threadID)
<span>'''Pendulum PID controller calcualtion'''</span>
''[_amgrp9fc67c72cd599f172740e6b41f919d72] Calculates PID controller for the Pendulum commands.''
This function sets up the calculation of the desired PID controller for the pendulum commands then calls the controller function. Finaly it converts the controller output to valid actuator commands and sens these commands to the actuators.
<span>Parameters</span>
the vrpn data of Eris
void ( <math>\ast</math>vrpnData)
<span>'''Eris PID controller calcualtion'''</span>
''[_amgrp966797ce8643a3dd9f9c9be64292a6f5] Calculates a PID controller for the Eris system.''
This function sets up the calculation of the desired PID controllers for Eris then calls the controller function. Finaly it converts the controller output to valid actuator commands and sens these commands to the actuators.
<span>Parameters</span>
the ponter to the vrpn data of Eris
void ( <math>\ast</math>vrpnData)
<span>'''User PID Tuner'''</span>
''[_amgrp19c4ee08c9dbcdaf609dc0a72c72d089] Used to tune the pendulum PIDs''
This UI is used to tune the pendulum PIDs. It doesn’t perminatly change the PID values in eris.cfg. You can also swithc control mode
<span>Parameters</span>
pionter to the pendulum vrpn data
void ( <math>\ast</math>vrpnData)
<span>'''Robot Control User Interface'''</span>
''[_amgrp1252ccc3177db21404c6dc4ed6a4eaa4] Lets users command Eris to move and change headding.''
The user can command Eris to move in x/y and rotate. The user can also change the command mode.
<span>Parameters</span>
The pointer to the pendulum VRPN data
void ( <math>\ast</math>vrpnData)
<span>'''Robot Control Mode'''</span>
''[_amgrp74ce911b6d1d37b44c2b8ce61152513b] Handles user inputs in robot control mode''
This function processes the user input from the UI when in rop=bot control mode.
void ()
<span>'''Tuning Mode'''</span>
''[_amgrpb934e8737cc509085ebb5f73b19acb1c] Hadles the user inputs when in tuning mode''
This function handers the user input when in tuning mode.
void ()
<span>'''Pendulum Box Step Mode'''</span>
''[_amgrp0dd1499b5cddba7f94d7e8d3984cd1c7] Causes the pendulum to move in a box when in PID mode.''
This function performs a demo by moving in a box formation (first moves to a corner from center, then steps around in a square). It takes 9 steps to be centered again.
This function uses the following global variables nextChange - Time in seconds of the next state change state - The current state - the position in the box boxSize - Angle size in radians of the box changeRate - Time in seconds between each state change
<span>Parameters</span>
is the current vrpn time
void (double curTime)
<span>'''Load Configuation Files'''</span>
''[_amgrped311958465031c00fa547e89c46a708] Loads eris.cfg from the NFS''
Lods the configuration file in the Configuration class
<span>Returns</span> bool value that for success or failure
bool ()
<span>'''UI Thread'''</span>
''[_amgrp62c5d6af5e738187ff22ed2cdba8093e] This is the main function for hte UI thread''
This thread just waits for user input (in the form of a single keypress). Once input is received, a global variable for the key is set so that the main thread can access the key that was pressed.
<span>Parameters</span>
is the thread ID
<span>Returns</span> NULL since it shouldn’t end in our case
void <math>\ast</math> (void <math>\ast</math>threadID)
<span>'''ctrl+c handler'''</span>
''[_amgrp99eb6333e039b04cc2ae3b28102e0bfa] this function exits the program correctly even when exiting via ctrl+c.''
This is a ctrl+c handler. It sets app_shutdown to 1, which should shut down the program. I am not sure of the specifics because this was written before the May15-27 team
<span>Parameters</span>
the signal that it receives when the key is pressed
static void (int sig)
<span>'''RADA LQI controller calcualtion'''</span>
''[_amgrpe30a3a342484e25b238d7c5cd8c27cbb] Calculates a LQI controller for the entier RADA system.''
This function sets up the calculation of the desired LQI controller then calls the controller function. Finaly it converts the controller output to valid actuator commands and sens these commands to the actuators.
<span>Parameters</span>
the vrpn data of the pendulum
the vrpn data of Eris
void ( <math>\ast</math>vrpnDataPen, <math>\ast</math>vrpnDataEris)
<span>'''RADA State-space controller calcualtion'''</span>
''[_amgrp23542f9ec756f55caa3591c437bfac56] Calculates a state-space controller for the entier RADA system.''
This function sets up the calculation of the desired state space controller then calls the controller function. Finaly it converts the controller output to valid actuator commands and sens these commands to the actuators.
<span>Parameters</span>
the vrpn data of the pendulum
the vrpn data of Eris
void ( <math>\ast</math>vrpnDataPen, <math>\ast</math>vrpnDataEris)
<span>'''RADA State-space controller calcualtion with packet loss'''</span>
''[_amgrpf56561d2b664983cbfcb2c50e691a9d8] Calculates a state-space controller for the entier RADA system under lossy conditions.''
This function sets up the calculation of the desired state space controller then calls the controller function. Finaly it converts the controller output to valid actuator commands and sens these commands to the actuators.
<span>Parameters</span>
the vrpn data of the pendulum
the vrpn data of Eris
void ( <math>\ast</math>vrpnDataPen, <math>\ast</math>vrpnDataEris)
<span>'''Test propellers at 50% commands'''</span>
''[_amgrp467ef14d3f83635ee95aefccc1c11b89] Runs the propeller motors at 50% of maximum command.''
The motors are tested at 50% of maximum command to determine what the effective batter voltage the ESCs see. This sould only be used to with the battery voltage measuing setup for te quadrotor in Chapter 5 of Paul hing’s thesis.
void ()
<span>'''RADA LQI controller with esitmation calcualtion'''</span>
''[_amgrp44e159876fd6aed6675462ea834d4ada] Calculates a LQI controller for the entier RADA system with esitmation.''
This function sets up the calculation of the desired LQI controller with esitmator, then calls the controller function. Finaly it converts the controller output to valid actuator commands and sens these commands to the actuators.
<span>Parameters</span>
the vrpn data of the pendulum
the vrpn data of Eris
void ( <math>\ast</math>vrpnDataPen, <math>\ast</math>vrpnDataEris)
<span>'''RADA LQG controller calcualtion'''</span>
''[_amgrpa91cac312d6bef2eb5e7e736994f4383] Calculates a LQG controller for the entier RADA system.''
This function sets up the calculation of the desired LQG controller then calls the controller function. Finaly it converts the controller output to valid actuator commands and sens these commands to the actuators.
<span>Parameters</span>
the vrpn data of the pendulum
the vrpn data of Eris
void ( <math>\ast</math>vrpnDataPen, <math>\ast</math>vrpnDataEris)
<span>'''Quadror LQG controller calcualtion'''</span>
''[_amgrp45f126903f6b8cbbb39832621800abd6] Calculates a LQG controller for the pendulum system.''
This function sets up the calculation of the desired LQG controller for the penduum then calls the controller function. Finaly it converts the controller output to valid actuator commands and sens these commands to the actuators.
<span>Parameters</span>
the vrpn data of the pendulums
void ( <math>\ast</math>vrpnDataPen)
<span>'''LQG controller calcualtion for Eris only'''</span>
''[_amgrp2fcbbf0d43176e1469cdb7ef2c01215d] Calculates a LQG controller for the Eris system.''
This function sets up the calculation of the desired LQG controller for Eris then calls the controller function. Finaly it converts the controller output to valid actuator commands and sens these commands to the actuators.
<span>Parameters</span>
the vrpn data of Eris
void ( <math>\ast</math>vrpnDataEris)
<span>'''Eris PID controller with open-loop calcualtion'''</span>
''[_amgrp5d5162a153e3702020f806e0b98a335a] Calculates PID controller for Eris with open-loop commands.''
This function sets up the calculation of the desired PID controller for Eris with open-loop commands then calls the controller function. Finaly it converts the controller output to valid actuator commands and sens these commands to the actuators.
<span>Parameters</span>
the vrpn data of Eris
void ( <math>\ast</math>vrpnData)
<span>'''Tic stopwatch starts'''</span>
''[_amgrpbe5fa55475c3c5cd3d3dde119cd0c839] Starts a stopwatch timer.''
This function will get the current time to start timing something.
Example Usage:
tic(); do_things; toc(); deltT():
void ()
<span>'''Toc stopwatch stops'''</span>
''[_amgrp7282852836645082f4d2dc3a1ee2f48f] Stops a stopwatch timer.''
This function will get the current time to stop timing something.
Example Usage:
tic(); do_things; toc(); deltT():
void ()
<span>'''Delta T stopwatch output'''</span>
''[_amgrp6c89f10ad681f33bea46252ec9ef66c1] Prints the length of execution of the last set of timed code.''
This function take the diefference between the start time and stop time and convert that to time in milliseconds. Then the function prints the time to the STD Out.
Example Usage:
tic(); do_things; toc(); deltT():
void ()
<span>'''Main function of RADA'''</span>
''[_amgrp9789cfd4cd4c15da3d3fa22ebb5abadd] This function intitializes the RADA test and hands execution to the threads.''
This function intializes the code execution by loading the configuration, intializing the motor controller settings, the , VRPN, and then hands the execution for the code to the VRPN thread and the main thread. The main tread is in charge of text based UI the user interacts with over SSH. The vrpn thread handles processing the VRPN data including controller calcualtions. There could be a thrid thread added to garentee that the packet drop controller runs every 10ms when packet drop controllers are run in a real enviorment (not simulating drops).
int (int argc, char <math>\ast</math><math>\ast</math>argv)
=== Variables ===
int
pthread_mutex_t
pthread_mutex_t
static char
const string = ‘"<math>\backslash</math>033H<math>\backslash</math>033J‘"
static double = 0
static = STOPPED
static = STOPPED
static FILE <math>\ast</math>
static unsigned char 2
static size_t
static ssize_t
static unsigned char = 0
static unsigned char = 0
= PITCH
static double = 0
static double = 20
static int = 0
static float = 0.0872664626
struct
static int = 35
static int = 0
static float = 9<math>\ast</math>0.0872664626
struct timeval startt
long
long
double
=== Detailed Description ===
main code that controls the data flow for running RADA
<span>Author</span> Paul Uhing, Ian McInerney, Dylan Gransee, Robert Larsen
<span>Date</span> July, 2016 This file setsup and controls the execution of the RADA system on Eris. ssTracking setsup reference tracking of inputs to control RADA when under H2 control. ssDrop puts the code in to packed drop mode and then RADA is controlled by a packed drop MSP controller. drop10 has the packet drop controller use a 10% drop controller design and forces the loss of 10% of packests. drop30 has the packet drop controller use a 30% drop controller design and forces the loss of 30% of packests. drop50 has the packet drop controller use a 50% drop controller design and forces the loss of 50% of packests. mot50 is used to test the actual propeller battery voltage at the ESCs after a test. The propellers are run at 50% command and the wheels are not commanded. RADAlqi causes RADA to be controlled by an LQI controller. FIR filters ae used to estimate velocities. RADAlqi_est causes RADA to be controlled by an LQI controller with a traditional estimator. rada_lqg causes RADA to be controlled by an LQG controller for the whole system. rada_split_lqg causes the pendulum and eris to be controlled by seperate LQG controllers. rada_split_lqg_ol causes the pendulum to be controlled by a LQG controller and the Eris to control its yaw with a PID and the linear velocities are controlled through open-loop commands. yaw_off turns off yaw control of Eris. H2ctrl puts RADA into a mode that uses an H2 controller to control RADA. ssMotors has RADA use an H2 controller that has propeller motor states in the controller design and will cause the system to ‘"dance.‘" accR sets up an acceration ramp for eris velocity control. posRamp causes Eris to control velocity as a postion ramp. If ssDrop, H2ctrl, RADAlqi, RADAlqi_est, rada_lqg, rada_split_lqg, or rada_split_lqg_ol are not defined then RADA will default to PID control. Make sure to edit the defines in to match the controllers used here.
=== Define Documentation ===
[main_8cpp_a4e084139c6a2952b2d8e3926f7a5d4dd] [main_8cpp_a994d9f112b804790cb294940eb9d323b] [main_8cpp_adea6f9fd5cbfe15ba103162c938c82c1] [main_8cpp_ad6c255586afaadad77cc9ead98c4c3ef] [main_8cpp_ad83c5423508a0de5baa15de51dda7dc5] [main_8cpp_a89551354e91f5016b1abcfaf16e940a3] [main_8cpp_a1ec7940bd8e2d994ebe311607d8300c9] [main_8cpp_a2a7307f445fd64358b32c0e3b7c1d97b]
=== Enumeration Type Documentation ===
[main_8cpp_ae3996976d8ffb3e58d88f58227473f8e]
; <span> ''[main_8cpp_ae3996976d8ffb3e58d88f58227473f8ea2eeb9fef8a6a516fa6437a44a6efbd52]'' </span>
:
; <span> ''[main_8cpp_ae3996976d8ffb3e58d88f58227473f8eaa4ed247aa19723caf868d2b2dd5cf4ff]'' </span>
:
[main_8cpp_a46c8a310cf4c094f8c80e1cb8dc1f911]
; <span> ''[main_8cpp_a46c8a310cf4c094f8c80e1cb8dc1f911a948b2aee15f52b421fa4770c47bcfe8c]'' </span>
:
; <span> ''[main_8cpp_a46c8a310cf4c094f8c80e1cb8dc1f911a5b098db3405ab997f1df697c8a25af60]'' </span>
:
; <span> ''[main_8cpp_a46c8a310cf4c094f8c80e1cb8dc1f911a8a1be19211abeacf191fa94e53a88df7]'' </span>
:
; <span> ''[main_8cpp_a46c8a310cf4c094f8c80e1cb8dc1f911a3f7641d93f9edd6dcef0ecbc9e5bcac2]'' </span>
:
=== Function Documentation ===
[main_8cpp_a21bf4fc6c3a34c923d42af1dd5980075] [main_8cpp_ace0ab8e44bfaa97bfcd82adb89d74854] [main_8cpp_ac9f02fb0114292a308e093f0d9f8aa30] [main_8cpp_adb0f7bc1fa10ac859582e433e7acc7dc] [main_8cpp_a1dbdf224e16e0509ac19e34c27bc37e7] [main_8cpp_aa19799b0e80b4e69de6b6cc3ade092c1] [main_8cpp_aac75d50db164b40415d3d80142fc4d2c] [main_8cpp_a4a20cd0821f9530e40398374ca1a4311] [main_8cpp_a3c04138a5bfe5d72780bb7e82a18e627] [main_8cpp_a568000bf542342c7b00ddb00afb93fd9] [main_8cpp_aa8c69f9e4a04bdaa5ce904551cae390d] [main_8cpp_ac94b9d8c47c3b310cd58bd94b0133783]
<math>\ast</math> [main_8cpp_a5669af9fd1cb16cbafe7bba476401d1e] [main_8cpp_aa48cf9381fdd01af90024b19545df7d4] [main_8cpp_aa8d50bf6758495a8070ea25c1e37e7f9] [main_8cpp_a728c70f1946e291f107c8c6e7a2ea65e] [main_8cpp_a1075d00c4632a01409111682ed506a4b] [main_8cpp_a16b090c977019835b449e0113e61a29b] [main_8cpp_a23c4b3cc92e1574ab3fd5522a51f274f] [main_8cpp_a898ef4198c44ab81d796a247d6a61458] [main_8cpp_ab5a1f466bba3d4b5cffc3697c11d218f] [main_8cpp_a7424442480a606c0febd38ec999c6af8] [main_8cpp_a5ba73899fe15846cc99820005d978e24] [main_8cpp_a3f604b0d492a343dd2c72ca7469b3cf7] [main_8cpp_a8f66738d39f61b6992e622acb683de6a] [main_8cpp_a6a64e00f10edf7b5f98ecae52de3427e] [main_8cpp_a40769a58f3fc191e9913aa92d53f527d]
=== Variable Documentation ===
[main_8cpp_ac32d6ad6c0714685f04b0130c7f77553] [main_8cpp_ad51e2c30d9b96de16e744f7ca54f3413] [main_8cpp_a4189bb97da233315f5721d38f82f10fe] [main_8cpp_ae565de10fdcd13a32c3deef98b10b045] [main_8cpp_a5d055a05b7de1e0898d6da92e2725e5e] [main_8cpp_a4565889a5449584de4acd8be53fefaf2] [main_8cpp_af29ec1ae9c2baac59d467be4d379f21e] [main_8cpp_abd94ded7cb6d0d29c553f52d2d926623] [main_8cpp_a1694170037849281e4db8c84dacc83ce] [main_8cpp_a2a9f405177eabe05143b129a3382e406] [main_8cpp_a57e5a12456f314ffc728d5d8da312970] [main_8cpp_a92459f6ff687f04fceaed1971c63fe89] [main_8cpp_af9b56b61a692a17c47d1e55b43b28320] [main_8cpp_a05067f85fb2548dbd7f1ba726256d60d] [main_8cpp_a4acff8232e4aec9cd5c6dc200ac55ef3] [main_8cpp_a6592d52d34d039c367f711900f17fdf7] [main_8cpp_acbd9a866ed8a9b963fee4f52d8fc9d48] [main_8cpp_a1e3954fef6954d324a4cea5118be77e9] [main_8cpp_a7dba94b79a26ddcc7a47f1b1fd880353] [main_8cpp_a28071e06a55fb35b53807b2292d77dac] [main_8cpp_a7bc6234247b5d8ec59319cb33b47b719] [main_8cpp_af6a35d8bda2bbb2656b29287230d8c81] [main_8cpp_ae7734f26f6b6e0008fe2b7884b2d4ac4] [main_8cpp_a0a07a521d3525b9b7dc70c0a625adea0] [main_8cpp_a89f234133d3efe315836311cbf21c64b] [main_8cpp_a4599153a1fb61e7bcdca1b8ea7aac88a] [main_8cpp_a3caf00a2855215688b02988d68d8b710]
These funtions initiaize controllers and do the actual controller calculation. <span>#include ‘"motor_controller.h‘"</span>
<span>#include <math><</math>iostream<math>></math></span>
<span>#include <math><</math>cstring<math>></math></span>
<span>#include ‘"ai.h‘"</span>
<span>#include ‘"configuration.h‘"</span>
<span>#include ‘"korebot.h‘"</span>
<span>#include ‘"localization_system.h‘"</span>
<span>#include ‘"Network/tcp_connection.h‘"</span>
<span>#include ‘"Network/network_bitstream.h‘"</span>
<span>#include ‘"Network/packets/motor_control_speed.h‘"</span>
<span>#include ‘"Network/packets/motor_control_manual.h‘"</span>
<span>#include ‘"Network/packets/configuration_packet.h‘"</span>
<span>#include ‘"DMCCom.h‘"</span>
<span>#include ‘"INCLUDE5.H‘"</span>
<span>#include ‘"IO5.H‘"</span>
=== Functions ===
<span>'''State Model'''</span>
''[_amgrpc4df07eb6e37e6b16df68627217435d1] Calculate a state controller.''
Calculates a controller using code autogenerate from a MATLAB conroller.
<span>Parameters</span>
The vector input to the controller asa double
is the location where the output is stored
void (const double u13, double y13)
<span>'''State Model Full Initialization'''</span>
''[_amgrp90df6d656fcc497e551f2b80226e3ae7] Initialize the state controller.''
Initializes a controller using code autogenerate from a MATLAB conroller.
void (void)
<span>'''State Model Terminalte'''</span>
''[_amgrpb57c89198c125d8a20eaf14eda168e0d] Terminalte the state controller.''
Terminates a controller using code autogenerate from a MATLAB conroller.
void (void)
=== State Space Controlelr Configuration ‘"Dance‘" ===
Initializes a state space controller.
This function initializes as state space controller (H2) that has states for the quadrotor motors and causes the system to ‘"Dance‘".
1 when the initialization is complete
static double 13
static void (void)
=== Detailed Description ===
These funtions initiaize controllers and do the actual controller calculation.
<span>Author</span> Dylan Gransee, Robert Larsen, Paul Uhing, Ian McInerney
<span>Date</span> July, 2016 These functions interact with actuators. This includes the actual controller calcuations, controller initialization, and sending the actuator commands to the FPGA. The namespace contains the data structures thqat store mast of the system’s data. Compiler macros are used to define a few modified calcuations. ssDrop defines a version the packet drop controller. posRamp defines the PIDs for the wheel velocity controllers so they are really postion controllers. LQI_strong defines a different LQI controller. ssMotors defines the H2 controller that makes the system ‘"dance.‘" ssTracking deines the H2 controlelr that will track reference inputs.
=== Function Documentation ===
[motor__controller_8cpp_a9ece9d0ee8318af42d3ea6a39c04438f] [motor__controller_8cpp_a50f56ed304c94c72900834bfee6880fb] [motor__controller_8cpp_ae0feaa1d69224c3c692ea4d015bf6772] [motor__controller_8cpp_aff2689042e650760bf8c24c25f98b459]
=== Variable Documentation ===
[motor__controller_8cpp_ad79f130e5c463fb8299547a7e40d3273]
<span>#include <math><</math>sstream<math>></math></span>
<span>#include ‘"motor_controller_common.h‘"</span>
<span>#include ‘"Network/packets/motor_control.h‘"</span>
<span>#include <math><</math>stddef.h<math>></math></span>
<span>#include <math><</math>stdlib.h<math>></math></span>
<span>#include <math><</math>string.h<math>></math></span>
=== Classes ===
class
=== Defines ===
#define 0.01
#define -500
#define 500
=== Functions ===
void (const double u13, double y13)
void (void)
void (void)
=== Define Documentation ===
[motor__controller_8h_a6f7e745f759b3e4035d8465798a4e075] [motor__controller_8h_a4d585ad2fa2a686567fe72cd14428dde] [motor__controller_8h_ac32e7bee9d8c1ee37bfae3e48852535d]
=== Function Documentation ===
[motor__controller_8h_a9ece9d0ee8318af42d3ea6a39c04438f] [motor__controller_8h_ae0feaa1d69224c3c692ea4d015bf6772] [motor__controller_8h_aff2689042e650760bf8c24c25f98b459]
<span>#include ‘"RADA_est.h‘"</span>
<span>#include ‘"RADA_split_LQG1.h‘"</span>
<span>#include ‘"RADA_LQG_s2.h‘"</span>
<span>#include ‘"packLoss0.h‘"</span>
=== Classes ===
struct
struct
struct
struct
struct
struct
struct
struct
struct
struct
struct
struct
struct
struct
struct
struct
=== Defines ===
#define 10
#define 5
#define 5
#define 13
#define 13
#define 13
#define 5
#define 8
#define 5
#define 8
=== Variables ===
const int = 40
static const double 513
=== Define Documentation ===
[motor__controller__common_8h_a955a986a03f5aeb6bf10e71895a3fdc3] [motor__controller__common_8h_a01d92c67268fde027859c170514a4302] [motor__controller__common_8h_a26fc6745fdc4de3ad2ee421fc25aad41] [motor__controller__common_8h_a517216260e9c5807ff1d17e6b6ccfeff] [motor__controller__common_8h_acab00577a38703b3785f3d2310227a83] [motor__controller__common_8h_aa5b8ec5acecfe7e95912d6b3d6f64bcd] [motor__controller__common_8h_a65bdc185b18744aeb24c1ed6b3f070ea] [motor__controller__common_8h_a145ce8a02c1957fca71b9e2e241b15b4] [motor__controller__common_8h_a16dd14f45595e42913f1ef8e51127484] [motor__controller__common_8h_af1ee1bb5f099e72114ef336dae59ef7c]
=== Variable Documentation ===
[motor__controller__common_8h_af72d10797fe016402e0f6b4784fb5f72] <span>'''Initial value:'''</span>
<span><span>89246, -1435, 0, 33, 2065, 26120, -420, 0, -78669, 1265, 0, 532, 33092</span>, <span>1435, 89246, 0, -2065, 33, 420, 26120, 0, -1265, -78669, 0, -33092, 53 2</span>, <span>0, 0, 34251, 0, 0, 0, 0, 1848, 0, 0, -43274, 0, 0</span>, <span>0, 10700, 0, 133545, 0, 0, -1685, 0, 0, 4740, 0, -802320, 0</span>, <span>-10700, 0, 0, 0, 133545, 1685, 0, 0, -4740, 0, 0, 0, -802320</span></span>
[motor__controller__common_8h_a3bf73988242d507676faf5e730c51951]
These are utility funtions. <span>#include ‘"utils.h‘"</span>
<span>#include <math><</math>cmath<math>></math></span>
<span>#include <math><</math>cstdio<math>></math></span>
<span>#include <math><</math>iostream<math>></math></span>
<span>#include <math><</math>termios.h<math>></math></span>
=== Functions ===
<span>'''Normalize Number'''</span>
''[_amgrp7182c311916e84625d4f869ea77768f4] Normalizes number from one range to another''
Normalizes a number within range A and B to be equivalent in range C to D
<span>Parameters</span>
is the number to be normaized
is the minimum value of the range of the input
is the maximum value of the range of the input
is the minimum value of the range of the output
is the maximum value of th erange of the output
<span>Returns</span> the new value normaized in in the new range as a double
double (double num, int A, int B, int C, int D)
<span>'''Radians to Dergrees'''</span>
''[_amgrpb9794915799365dc1c3fa4144041f823] Converts a radians to degrees.''
Radians to degrees convertion utility function
<span>Parameters</span>
is the angle in radians to be converted as a double
<span>Returns</span> the inital angle converted to degrees as a double
double (double angle)
<span>'''Get character'''</span>
''[_amgrp330971785c699ebf40c4e9e8bcc083e9] Gets the keyboard comands from the user.''
Gets the key board commands from the user. This works with the user interface and must be blocking as it has its own thread.
the charater pressed on the user’s keyboard
char ()
=== Detailed Description ===
These are utility funtions.
<span>Author</span> Dylan Gransee, Robert Larsen
<span>Date</span> July, 2016 These utility functions can be used to normalize data, convert angle units and get input from a keyboard.
=== Function Documentation ===
[utils_8cpp_af3facad10e05defa48d45b46eb9ebe7e] [utils_8cpp_a3c082bb8a8bc92f9531055f7dd87f29e] [utils_8cpp_a45cf2c44832d15363ce9ea6ecb67a6ba]
=== Functions ===
double (double num, int A, int B, int C, int D)
double (double angle)
char ()
=== Function Documentation ===
[utils_8h_af3facad10e05defa48d45b46eb9ebe7e] [utils_8h_a3c082bb8a8bc92f9531055f7dd87f29e] [utils_8h_a45cf2c44832d15363ce9ea6ecb67a6ba]
These funtions interact with the VRPN library. <span>#include ‘"vrpn.h‘"</span>
<span>#include <math><</math>unistd.h<math>></math></span>
=== Functions ===
<span>'''Initialize VRPN'''</span>
''[_amgrp20a78012704698ef784ff27869f78644] This funtion initializes the VRPN client that receives information about the UAV (pendulum) and trackables.''
This funtion intilialises the VRPN link with the camera system using the defined IP address to listen for data from and what port to listen at. This initializes the trackable C++ object for the two camrea system constenlation this system needs to look for.
void (std::string connectionName, void(<math>\ast</math>callback)(void <math>\ast</math>, const vrpn_TRACKERCB), void(<math>\ast</math>callback1)(void <math>\ast</math>, const vrpn_TRACKERCB))
<span>'''VRPN Go Process Trackables'''</span>
''[_amgrpecbaa586fe612dd88809d85ebee6a568] This loop continously checks for new trackable data then processes it using the VRPN library.''
This function loops forever chencking the VRPN connection for new data then processing the trackable data when it recives new trackable data for constellations it is listening for.
void ()
=== Variables ===
vrpn_Connection <math>\ast</math>
vrpn_Tracker_Remote <math>\ast</math>
vrpn_Tracker_Remote <math>\ast</math>
=== Detailed Description ===
These funtions interact with the VRPN library.
<span>Author</span> Dylan Gransee, Robert Larsen, Paul Uhing
<span>Date</span> July, 2016 These funtions are used to interact with the VRPN data being broadcast by the camera system.
=== Function Documentation ===
[vrpn_8cpp_aad572d3b2e50ca74bc1cbb7095bb10e6] [vrpn_8cpp_aa23c89cec3a84dfd2217574495042ed1]
=== Variable Documentation ===
[vrpn_8cpp_a82358f6a74652dcb4c021fcaf08132b0] [vrpn_8cpp_aafcf6a4836ee8542ec8b2e8bcecebd2e] [vrpn_8cpp_a1808fc275087d0affb46825e96f5f7ed]
<span>#include ‘"vrpn_Connection.h‘"</span>
<span>#include ‘"vrpn_Tracker.h‘"</span>
=== Classes ===
struct
=== Functions ===
void (std::string connectionName, void(<math>\ast</math>)(void <math>\ast</math>, const vrpn_TRACKERCB), void(<math>\ast</math>callback1)(void <math>\ast</math>, const vrpn_TRACKERCB))
void ()
=== Variables ===
static const std::string = ‘"192.168.0.196‘"
static const int = 60560
static const int = 8
=== Function Documentation ===
[vrpn_8h_aad572d3b2e50ca74bc1cbb7095bb10e6] [vrpn_8h_ac6e5e1f9755d0d510c997af6ee86c2c9]
=== Variable Documentation ===
[vrpn_8h_a352f55c57b6223930012cfd93bc03485] [vrpn_8h_a2cbd02aedf20e63c4a0be4c28afc976d] [vrpn_8h_a24ee7d8017cbda77544b28c99880eca1]
30c40c62a99df5b23d6e4af2bf53b26bb0a3a000
282
281
2016-08-04T19:35:01Z
Pfuhing
5
Replacing page with 'test'
wikitext
text/x-wiki
test
a94a8fe5ccb19ba61c4c0873d391e987982fbbd3
File:HandModeTimingFigure.JPG
6
70
300
238
2016-08-27T17:59:02Z
Jnoronha
3
Jnoronha uploaded a new version of [[File:HandModeTimingFigure.JPG]]
wikitext
text/x-wiki
Hand Mode timing plot produced by the matlab logfile parser
ebaca8b8857776b9ef950bf6d7cdf786cbbf37f1
File:HandModeTimingFigure.JPG
6
70
301
300
2016-08-27T17:59:52Z
Jnoronha
3
Jnoronha uploaded a new version of [[File:HandModeTimingFigure.JPG]]
wikitext
text/x-wiki
Hand Mode timing plot produced by the matlab logfile parser
ebaca8b8857776b9ef950bf6d7cdf786cbbf37f1
File:HandModePlot.jpg
6
69
302
237
2016-08-27T18:00:24Z
Jnoronha
3
Jnoronha uploaded a new version of [[File:HandModePlot.jpg]]
wikitext
text/x-wiki
Hand Mode demo plot produced by the matlab logfile parser
b68031a6bf9dcc7b0a69a5763515d6025eda6087
File:YPositionPlot.png
6
68
303
236
2016-08-27T18:00:54Z
Jnoronha
3
Jnoronha uploaded a new version of [[File:YPositionPlot.png]]
wikitext
text/x-wiki
Y position plot produced by the matlab logfile parser
0cbfa9ce48512c39aeee38c0b9d34ec8a20e813d
File:XPositionPlot.png
6
67
304
235
2016-08-27T18:01:33Z
Jnoronha
3
Jnoronha uploaded a new version of [[File:XPositionPlot.png]]
wikitext
text/x-wiki
X position plot produced by the matlab logfile parser
e330d18c0d830813b11e4a5551b13d1e20d2a2e5
File:TrackingToolsCrazyflieConstellationParams.png
6
45
305
147
2016-08-27T18:02:12Z
Jnoronha
3
Jnoronha uploaded a new version of [[File:TrackingToolsCrazyflieConstellationParams.png]]
wikitext
text/x-wiki
Camera System Software with Crazyflie and Hand Constellations and Server Port Info
432e585d1f7446ecf7d98fcc6976aaeedbcd9b9e
File:TrackingToolsCrazyflieConstellationZeroing.png
6
43
306
145
2016-08-27T18:02:33Z
Jnoronha
3
Jnoronha uploaded a new version of [[File:TrackingToolsCrazyflieConstellationZeroing.png]]
wikitext
text/x-wiki
Camera System Software with Crazyflie and Hand Constellations loaded
b20b4b16a3427dc104687a0ec094c2df21a8b1d5
File:CrazyflieTerminalRadioDriverNotDeleted.png
6
38
307
93
2016-08-27T18:03:06Z
Jnoronha
3
Jnoronha uploaded a new version of [[File:CrazyflieTerminalRadioDriverNotDeleted.png]]
wikitext
text/x-wiki
Crazyflie Terminal showing Error if Radio Driver was not properly deleted. (Unplug and Re-plug Radio Dongle)
d0b2014bc578e0e9c5b8c64f7855eaf84ab407a5
File:CrazyflieTerminalNoRadio.png
6
37
308
92
2016-08-27T18:03:29Z
Jnoronha
3
Jnoronha uploaded a new version of [[File:CrazyflieTerminalNoRadio.png]]
wikitext
text/x-wiki
Crazyflie Terminal showing Error Garbage if no Radio plugged in.
b33575b3a31b2001e05e2cd3f58ccb1118990e3b
File:CrazyflieTerminalKeyboardInput.png
6
36
309
91
2016-08-27T18:03:53Z
Jnoronha
3
Jnoronha uploaded a new version of [[File:CrazyflieTerminalKeyboardInput.png]]
wikitext
text/x-wiki
Crazyflie Terminal showing Swarm Client after keyboard input has been pressed
b1a82197fcc216cdc42515cc3ec6fff3bda23b0d
File:CrazyflieTerminalProgramStarted.png
6
35
310
90
2016-08-27T18:04:23Z
Jnoronha
3
Jnoronha uploaded a new version of [[File:CrazyflieTerminalProgramStarted.png]]
wikitext
text/x-wiki
Crazyflie Terminal showing Swarm Client ready for keyboard input
17a5d428fc8c01f3bab6f28028b083544f9dcd8d
File:CrazyflieTerminalRunProgram.png
6
34
311
89
2016-08-27T18:05:25Z
Jnoronha
3
Jnoronha uploaded a new version of [[File:CrazyflieTerminalRunProgram.png]]
wikitext
text/x-wiki
Crazyflie Terminal showing the run .exe command
9d78db40abd506e403e8e7da4dae4fc9c9fdf42a
File:CrazyflieTerminalPostMake.png
6
32
312
87
2016-08-27T18:06:12Z
Jnoronha
3
Jnoronha uploaded a new version of [[File:CrazyflieTerminalPostMake.png]]
wikitext
text/x-wiki
Crazyflie Terminal showing an error free make build
d6cea0bf6c7a21708537aa1d95eead63570705c8
File:CrazyflieTerminalInitial.png
6
31
313
86
2016-08-27T18:06:31Z
Jnoronha
3
Jnoronha uploaded a new version of [[File:CrazyflieTerminalInitial.png]]
wikitext
text/x-wiki
Crazyflie Terminal showing the make command
c6f990d31f07dfcf8d93d9f828ea053eeb121328
File:DefaultCrazyflieGUIParametersScreen.JPG
6
29
314
77
2016-08-27T18:07:18Z
Jnoronha
3
Jnoronha uploaded a new version of [[File:DefaultCrazyflieGUIParametersScreen.JPG]]
wikitext
text/x-wiki
Screenshot of the Crazyflie GUI Parameters Tab
ef7255336a61589fd230dbc1017eae357b6ae0be
File:DefaultCrazyflieGUILoggerScreen.JPG
6
28
315
76
2016-08-27T18:07:41Z
Jnoronha
3
Jnoronha uploaded a new version of [[File:DefaultCrazyflieGUILoggerScreen.JPG]]
wikitext
text/x-wiki
Screenshot of the Crazyflie GUI logging output
8fb3c169c5958e65b424b65fa95db06f05872b2e
File:DefaultCrazyflieGUIConnectScreen.JPG
6
27
316
75
2016-08-27T18:08:09Z
Jnoronha
3
Jnoronha uploaded a new version of [[File:DefaultCrazyflieGUIConnectScreen.JPG]]
wikitext
text/x-wiki
Screenshot of the Crazyflie GUI connect to radio window.
4c03f28f200c96bb4f336f5e667304c98f3b4037
Crazyflie Swarm
0
2
317
268
2016-08-27T18:15:41Z
Jnoronha
3
/* Bitcraze Wiki */ added link in description too
wikitext
text/x-wiki
The Crazyflie Swarm is a Networked Control platform designed for students to learn more about control and for researchers that wish to apply their research in practice. Platform development was started during the Summer of 2015 and continues to this day.
Here you will find descriptions on how the platform works, how you can use it, and how you can get involved in developing the platform further!
== Frequently Asked Questions ==
For help with common problems and troubleshooting please see the [[FAQ]].
== Background ==
The Crazyflie Swarm platform is based off of the ''Crazyflie'' Nano-quadcopter produced and maintained by [https://www.bitcraze.io/ Bitcraze]. The ''Crazyflie'' is completely open-source so we are able to look at and modify any part of the code and customize it to our needs.
=== Major Platform Components: ===
[[Image: High_Level_Figure_(Single_Radio_Single_Crazyflie_NO_NUMBERS_CROPPED).jpg|thumb|right|A high level overview of the Crazyflie Platform]]
*[[PC Client Software]]
*[[Firmware]]
*[[USB Radio]]
== Modifying the Platform ==
[[Image:SingleRadioMultiCrazyflie.jpg|thumb|right|A high level overview of the Swarm Platform we created]]
*[[Controller]]
*[[Logging]]
*[[Keyboard Commands]]
*[[USB Radio#Changing Radio Channel|Changing Radio Channel]]
*[[Flight Modes]]
*[[Callbacks]]
*[[Adding a Crazyflie]]
*[[:Firmware]]
==Future Project Ideas==
The whole concept of this Platform is to constantly expand its capabilities. If you are interested in developing this platform further here are some ideas to get you started! Additional details on any of these ideas can be found on the '''[[Future Project Ideas]]''' page.
*[[:Future Project Ideas#Migrating Swarm Client PID's to Firmware|Migrating Swarm Client PID's to Firmware]]
*[[:Future Project Ideas#Model Development/Verification and Tuning X, Y, and Z Location PID's|Model Development/Verification and Tuning X, Y, and Z Location PID's]]
*[[:Future Project Ideas#Adding Parameter Support to Swarm Client|Adding Parameter Support to Swarm Client]]
*[[:Future Project Ideas#Threading Each USB Radio to speed up Computation|Threading Each USB Radio to speed up Computation]]
*[[:Future Project Ideas#Developing New Controllers for the Crazyflie (pending Model Development)|Developing New Controllers for the Crazyflie (pending Model Development)]]
*[[:Future Project Ideas#Develop Communications Network Between Crazyflies|Develop Communications Network Between Crazyflies]]
*[[:Future Project Ideas#Trilateration Position Estimation using a Swarm|Trilateration Position Estimation using a Swarm]]
== [https://wiki.bitcraze.io/ Bitcraze Wiki] ==
Bitcraze maintains their own wiki on the many Crazyflie systems. If you can't find what you are looking for [https://wiki.bitcraze.io/ here], chances are they will have something to help.
8ebd85d0e68e5c5143f082e528f0e184413a3bed
Data Collection and Simulation Comparison
0
50
318
260
2016-08-27T22:02:54Z
Jkgrund
4
/* Charging batteries */
wikitext
text/x-wiki
This page will take you though setting up and testing RADA, retrieving the log file and other necessary data to run a simulation of that test and processing the data in MATLAB. Then actually running the simulation of RADA in Simulink. The initial setup and how to test the system can also be applied to demoing RADA.
== Setting Up a RADA Test ==
Testing RADA is not overly difficult once you get the hang of the steps to setup RADA. The following steps may seem like a long process to go from starting the testing process to having completed simulation and plotting of the test results but this whole test procedure (with the exception of battery charging) can be completed in about 15-20 minutes. These steps are meant to be as detailed as possible in order to help new users of RADA to get up and running as quickly as possible.
'''<span style="color:red">NOTE: Always run RADA with at least 2 people!</span>''' The pendulum arm can crash into the ground if the network starts to drop packets and one person cannot give commands to RADA and spot the pendulum. This is a safety issue for both you and the RADA platform.
=== Charging batteries ===
The lab currently uses mostly Hyperion batteries. We charge our batteries with a Hyperion EOS 1420i Net3 battery charger. For some general information about how to use this charger see [https://www.youtube.com/watch?v=-ox3EpzvsJ8 this video.]. In the lab we power this charger using the old Kepco Power supplu because it is the only power supply that we have that can supply enough current. Make sure that the power supply is set to an output voltage between 10.5V-29V.
{| class="wikitable" style="text-align:center"
|-
| [[Image:ChargerPowerSupplyOff.JPG|400px]]
| [[Image:ChargerPowerSuplyOn.JPG|400px]]
|-
| Kepco Power Supply off.
| Kepco Power Supply on with correct voltage supply range.
|}
While the YouTube video linked above should explain how to use the charger. Currently three different Lithium polymer batteries (Lipo): 1600 mAh 2-cell Lipo for the wheels, 2600 mAh 2-cell Lipo for the electronics of Eris, and a 2600 mAh 4-cell Lipo. The 1600 mAh 2-cell Lipo can be charged using memory slot 2 of the charger. The 2600 mAh 2-cell Lipos can be charged using memory slot 3 for fast charging and memory slot 4 for slower charging (use this if the battery gets run really low for 10-20 minutes then switch to fast charging). The 2600 mAh 4-cell Lipo can be charged using memory slot 8. The 1600 mAh 2-cell and 2600 mAr 4-cell generally charge in 10-20 minutes apiece while I generally fine it takes the 2600 mAh 2-cell up to 70 minutes to charge fully.
=== Setting up the camera system ===
The camera system is run on the windows computer CO3050-07. You can log into this computer using a local microcart username and password which is not posted here for security reasons but any one who works in the lab should know it. Once logged in look for Tracking Tools in the start menu or look for the shortcut shown below:
[[Image:TrackingTools_shortcut.PNG|thumb|center|Tracking Tools shortcut]]
Once the program opens the screen should look something like this:
[[Image:NewTrackingTools.PNG|800px]]
In the Tracking Tools Quick Start pop up menu select Open Existing Project and then navigate to ''D:\Optitrack_Configuration'' (It should open to this directory by default) and select the most recent Tracking Tools project. It should be named like ''TrackingToolsProject YYYY-MM-DD timeStamp.ttp''. This is normally the most recently edited file when sorting by data modified. The most recent one as of August 1st, 2016 is ''TrackingToolsProject 2015-09-23 2.30pm.ttp''.
[[Image:OpeningProject.PNG|800px]]
You should notice that the cameras shown in main project scree arrange themselves like out camera configuration once the project has been opened. Now the constellations need to be loaded. This can be done by going to ''File->Open'' and another pop up window will open. Navigate back to ''D:\Optitrack_Configuration'' (It should open to this directory by default) and select the most recently dated set of RADA trackables. They are named like ''RADA_entireSystem_M_D_YYYY.tra''. The most recent one as of August 1st, 2016 is ''RADA_entireSystem_7_8_2016.tra''.
[[Image:Opening_trackables.PNG|800px]]
Once the project and trackless are open the cameras should appear in their constellation (square) and there should be two constellations under ''Project Explorer->Trackables''. One Named UAV for the pendulum and one named ERIS for the ground vehicle. In order to get additional information about each constellation left click on the the name of the desired trackable.
[[Image:SelectingUAV.PNG|800px]]
Once a trackable is selected more information about it is available in the ''Trackables'' Tab on the right side of the screen. For the current position and orientation look at the ''Real-Time Info'' sub-tab. This gives the orientation in the wrong order for how we currently use the Euler angles. When two or three of the angles are near zero you can switch yaw and pitch to get roughly the correct orientation.
[[Image:Uav_realTimeInfo.PNG|800px]]
Now we need check to make sure the system is zeroed.
1. Hold RADA so that the front of the ground robot (ERIS is facing the wall with the white boards (east)). The front side of Eris is labeled. If it isn't it is the side opposite of the switches and the side with the trackable constellation on it.
2. Make sure that the motor with the red motor mount is also facing the wall with the white boards.
3. Make sure the quad system is aligned along Eris Axis by standing behind the system and seeing if you can use the pole to block mounting bolts of the front propeller motor mount when looking at the pole while facing the east wall.
4. While holding the pendulum approximately vertical see if the camera system reads zeros for the pendulum (UAV) pitch and roll (yaw and roll in ''Real-Time Info''). If yaw is off by a few degrees that is fine.
5. Compare the yaw of the UAV to that of ERIS (Remember this is pitch in ''Real-Time Info''). If they are both near zero and with in a few degrees and the pendulum's pitch/roll were also near zero then you are ready to use the camera system. Otherwise go to the next step.
6. You need to zero the pendulum.
- Align ERIS so it is near zero yaw first (eye ball it).
- Get a level and a friend. Have your friend use a level to ensure that the pendulum is level in both directs and hold it there.
- With the UAV constellation selected go to the ''Orientation'' tab (next to ''Real-Time Info'' tab) and click on ''Reset To Current Orientation button''
- Now your friend can set the pendulum down and you can zero ERIS the same way.
7. Save the new trackable orientation by going to ''File->Save Trakables...'' and save a file using the same naming conventions as the trackable file you opened earlier except use the current data so you don't have to re-zero the system the next time you test.
[[Image:Uav_ResetOrientation.PNG|800px]]
=== Building Software ===
The development environment for running RADA is hosted on CO3050-11, a Linux Red Hat environment. This computer has a local ucart user name that you should use. The password isn't put here for security reasons. In order to ensure that the RADA software is setup correctly for the test you want to run. To do this you will need to open the main.cpp and logger.cpp files and make sure all of the compile time macros you want are defined correctly. All of the c++ files you should need to edit are in the directory ''~/Desktop/rada_research_project/ErisResearchCode/CppProjects/MainProgram_PacketLoss/src/Korebot'' Below is a compiler macro options for main.cpp:
-'''H2ctrl''' : This will cause the system to enter H2 controller mode where the whole RADA system is controlled by an H2 controller.
-'''ssTracking''' : H2ctrl must also be defined for this macro to do anything. This macro will has the system to be controlled by a tracking H2 controller.
-'''ssMotors''' : H2ctrl must also be defined for this macro to do anything. This macro will has the system to be controlled by an H2 contorller that contains propeller states. This also cause the system to "Dance."
-'''ssDrop''' : Cause the system to go into packet drop controller mode. This mode allows controllers designed for lossy networks to be tested. Based off of other definitions how lossy the network is can be simulated. If nothing else is defined this controller becomes basically a H2 controller.
-'''drop10''' : Will put the packet drop mode into 10% loss mode and use a controller designed for 10% loss.
-'''drop30''' : Will put the packet drop mode into 30% loss mode and use a controller designed for 30% loss.
-'''drop50''' : Will put the packet drop mode into 50% loss mode and use a controller designed for 50% loss.
-'''mot50''' : This macro over-rides all other macros. If this is turned on the wheels will not run and the propllers will be run at 50% command. This is used for measuring the effective battery voltage seen by the ESCs. This is always run after a test.
-'''RADAlqi''' : This macro will cause the system to use an LQI controller on the whole system. The linear velocity states are calculated with no filter and the angular velocity states are calculated with filters.
-'''RADAlqi_est''' : This macro will cause the system to use an LQI controller on the whole system. A traditional estimator is used to estimate the states.
-'''rada_lqg''' : This macro will cause the entire system to be controlled by a LQG controller/estimator system.
-'''rada_split_lqg''' : This macro will cause the pendulum and ground robot to be controlled by their own LQG systems.
-'''rada_split_lqg_ol''' : This macro will cause the pendulum to be controlled by an LQG controller, the yaw of the ground robot to be controlled by a PID controller, and the ground robot linear velocities to be controlled with open-loop commands.
-'''yaw_off''' : This macro will cause the yaw control to be disabled on some controllers.
*'''accR''' : This macro will cause the PID linear velocity controllers to be given ramps to acclerate from one velocity to another instead of steps.
-'''posRamp''' : This macro will cause the linear velocities of RADA to be controlled by position PIDs with ramp reference instead of velocity commands.
-If no controller selection is made all controllers revert to PID controllers
All of these macros can be defined simply by uncommenting the corresponding define statement in main.cpp. The macros in the logger.cpp can be seen below:
-'''ssDrop''' : This macro puts the logger into packed drop controller mode and logs the correct values for the packet drop controllers.
-'''RADAlqi''' : This macro puts the logger into full system LQI controller logging mode.
-'''RADAlqi_est''' : This macro puts the logger into full system LQI controller plus estimator logging mode.
-'''rada_lqg''' : This puts the logger into full system LQG controller logging mode.
-'''rada_split_lqg''' : This macro causes the logger to log data about the subsystem LQG controllers.
-'''rada_split_lqg_ol''' : This cause the system to log data about the pendulum LQG system and the open-loop linear velocity commands.
-'''H2ctrl''' : This macro causes the logger to log data about the full system H2 controllers.
-If no logging mode is selected then the logger will default to logging PID data.
Because the system only calculates controllers for one set of controllers it is important to ensure that the logger is in the correct mode based off of what is defined in main.cpp. As of August 1st, 2016 the defines in main.cpp are not seen in logger.cpp.
Finally in a command prompt navigate to the driectroy: ''~/Desktop/rada_research_project/ErisResearchCode/CppProjects/MainProgram_PacketLoss''
Here just type: ''make''. The code will compile for your desired mode. For setting up a new development directory see [http://wikis.ece.iastate.edu/robotic-agriculture-data-acquisition/index.php/Setting_up_a_new_development_environment Setting up a new development environment] from the RADA senior Design wiki.
[[Image:ComplingRADACode.png|800px]]
The complied executable code ends up in ''/home/shared/MainProject''. The ''/home/shared'' directory is setup as a network file share (NFS).
[[Image:ErisCompliedCode-config.png|800px]]
This service needs to be restarted when CO3050-11 is restarted. [http://wikis.ece.iastate.edu/robotic-agriculture-data-acquisition/index.php/Configuring_NFS_shares_for_the_robot Configure NFS shares for the robot] from the RADA Senior Design wiki. Be sure to use the new Linux install command in step six. Though I have fond that even on a good strt the ''[ok]'' messages will still print.
=== Turing on RADA ===
Turing on Eris is fairly simple. Each system has its own battery. There is one for the wheels that plugs in at the front of Eris (opposite side of the swiches), one for the electronics in the back of Eris (in between the switches), and one for the propellers that goes on top of Eris.
[[Image:ErisOnPhoto.jpg|800px]]
The wheel battery is normally 1600 mAh 2-cell Lipo but any 2-cell Lipo will work. The wheels are turned on by flipping the silver switch so the top points away from the system. The electronics normally use a 2600 mAh 2-cell Lipo. The electronics are turned on by flipping the green switch away from the system. It is important that you only the WIFI adapter or Ethernet plugged in at the same time or VRPN my listen to the camera data broadcast over both connects which could cause problems. The propeller system is powered via a 2600 mAh 4-cell Lipo that connects to a power cable at the base of the pendulum. There is a switch to turn on the power to the propellers system. You will know it is on when the 1 on the switch is flush with the switch housing instead of sticking out. It takes about 30 seconds to a minute for Eris to boot up and start the networking connections. When the WIFI is plugged in you will know it is ready when a blue light turns on, on the module.
=== Connecting to RADA ===
RADA is controlled through an SSH connection. in a commands prompt, not the one you compile the code from so that you can recompile for different setup with out needing to close the connection. If you are using a WIFI connect use the command ''ssh root@192.168.0.53''. If you are connected to Eris through a LAN connaction use the command ''ssh root@192.168.0.54''. If the connection goes though you should be proped for a password.
The password is ''rootme''.
[[Image:Ssh2Eris.png|800px]]
It is important to close the SSH connection before turning off Eris because the terminal you are using will hang up if you don't. You can close the connection by using the command ''exit''.
[[Image:ClosingSSH.png|800px]]
== Testing RADA ==
Now that you are connected to Eris you can run tests. The testing is started by a few different methods.
=== Running the first test after power up ===
For the firs test after powering on Eris a few additional steps need to be completed in order to test the system. The FPGA motor controller needs to be programmed and Eris needs to connect the the NFS server running on CO3050-11. This is accomplished by running ''1_co3050-11.sh'', this shell scrip will setup the NFS, load the bit file into the FPGA configuration memory. Then it retrieves the executable file from the NFS server ''/mnt/nfs/MainProject and runs the executable. Once the user exits the executable the log file produces is copied from the ''~/Logs/YYYY_MM_DD_Day'' directory on Eris to ''/home/shared/MainProject/Logs/YYYY_MM_DD_Day'' on CO3050-11. When the folder for the current Eris date doesn't exist it creates this directory in CO3050-11 and then removes the directory and log file from Eris. You may see an warning that when coping the log file Eris couldn't maintain the file permisiion settings. This is normal as Eris doesn't have the same access to the NSF server as it has to its own files. This Date stamp uses date on Eris which is currently in June of 2008 as of August 2nd, 2016.
Before starting the test it is best to have someone spotting the pendulum a holding it near vertical so that the pendulum doesn't have issues when entering a control mode.'''<span style="color:red"> Always run ensure the pendulum is spotted by a second person when testing so you don't hurt yourself, others in the lab, or the RADA system.</span>''' Once you spotter is ready run the shell scrip by= using the command ''./1_co3050-11.sh'' in the terminal with the open SSH connection to Eris from the home, ''/root'', directory of Eris. When you run this script there will be a bunch of information printed out about the PIC bus and loading the bit file to configure the FPGA, you will know that RADA is ready for the test when it asks you to select a running mode. See the Testing Modes section below. This script can take a while to complete so beyond the first test after start up you don't need to run this script. See the Section about Running additional tests below.
[[Image:StartingRADA initial.png|800px]]
=== Testing Modes ===
The RADA system has three testing modes: Robot Control Mode, Tuning Mode, and Box Step Mode. Additionally you can exit the execution at any time by pressing the ''Esc'' key. Once the terminal asks you to chose a mode you can use the following commands to enter the desired mode with a three second delay or exit the program. You can also use these commands to switch between the modes.
-''v'' : Enters the pendulum PID tuning mode, this will only really work when using PIDs to control the pendulum.
-''b'' : Enter Robot control mode, in this mode you can drive the robot around and the pendulum will try to stay vertical. This is the main mode used for testing the whole RADA system.
-''n'' : Enters box step mode, where the pendulum will change its desired pitch and roll angles every 20 seconds and move in a box shape.
-''Esc'' : By hitting the escape key the program will exit the program.
You will almost always want to run Robot Control Mode as the other modes are legacy modes from when we initially built and tested RADA and only works with the pendulum PID controllers. There are also a few utility commands that can be used in all modes.
-''2'' : Resets I composts of the Pitch/Roll PIDs and only the PIDs.
-''m'' : Adds a marker to the Log file incase odd things happen somewhere. This just increments a counter so if you use it look for changes in the marker value.
==== Robot Control Model ====
In Robot control mode you can control the motion of Eris. For PID control of Eris or 1D state feedback system the directional commands command Eris body velocity were for full system and Eris system state feedback controllers control the global velocity. All of these keys only need to be pressed not held down.
-''w'' : Moves Eris forward (+x) at some velocity depending on the controller.
-''s'' : Moves Eris in reverse (-x) at some velocity depending on the controller.
-''d'' : Moves Eris in right (+y) at some velocity depending on the controller.
-''a'' : Moves Eris in left (-y) at some velocity depending on the controller.
-''p'' : Stops the motion of Eris (Set all velocity set points to zero). I.e. if you hit ''w'' then hit ''s'' then Eris will be moving in reverse.
-''y'' : Moves Eris forward and to the right (+x/+y) simultaneously at some velocity depending on the controller.
-''t'' : Moves Eris forward and to the left (+x/-y) simultaneously at some velocity depending on the controller.
-''i'' : Moves Eris reverse and to the right (-x/+y) simultaneously at some velocity depending on the controller.
-''y'' : Moves Eris reverse and to the left (-x/-y) simultaneously at some velocity depending on the controller.
-''e'' : Rotate Eris clockwise (+yaw) at some angular rate. This only worked when RADA used the closed-loop FPGA control of the wheels. There is currently no controllers that use this command.
-''q'' : Rotate Eris counter-clockwise (-yaw) at some angular rate. This only worked when RADA used the closed-loop FPGA control of the wheels. There is currently no controllers that use this command.
-''<'' : Increment Eris' desired heading 45 degrees counter-clockwise (-yaw).
-''>'' : Increment Eris' desired heading 45 degrees clockwise (+yaw).
-''7'' : Increments the pitch set point (+pitch).
-''4'' : Decrements the pitch set point (-pitch).
-''8'' : Increments the roll set point (+roll).
-''5'' : Decrements the roll set point (-roll).
==== Tuning Mode ====
Tuning mode allows you to tune the PID controllers for both pitch and roll. The UI commands here are also available in Box Step Mode.
-''1'' : Tune the Pitch PID.
-''3'' : Tune the Roll PID.
-''7'' : Increase proportional gain of PID being tuned.
-''4'' : Decrease proportional gain of PID being tuned.
-''8'' : Increase integral gain of PID being tuned.
-''5'' : Decrease integral gain of PID being tuned.
-''9'' : Increase derivative gain of PID being tuned.
-''6'' : Decrease derivative gain of PID being tuned.
-''i'' : Increase set point of PID being tuned.
-''k'' : Decrease set point of PID being tuned.
-''o'' : Increase integral windup term of PID being tuned. (Not used)
-''l'' : Decrease integral windup term of PID being tuned. (Not used)
==== Box Step Mode ====
Box set mode will automatically change the set points of the pendulum every 20 seconds. The case statement for this mode can be changed for 1D and 2D step modes. This mode allows the user to use he same commands as Tuning Mode.
=== Running additional Tests ===
Once you have run one test with Eris on it is unnecessary to configure the FPGA or connect to the NFS server again. This is what took much of the time in the initial setup. This is what the script ''3_stat_eris.sh'' was developed for. It does everything that ''1_co3050-11.sh'' does but without reprogramming the FPGA or reconnecting to the NFS server. As a result it is ready to test much quicker.
Before starting the test it is best to have someone spotting the pendulum a holding it near vertical so that the pendulum doesn't have issues when entering a control mode.'''<span style="color:red"> Always run ensure the pendulum is spotted by a second person when testing so you don't hurt yourself, others in the lab, or the RADA system.</span>''' Once you spotter is ready run the shell scrip by= using the command ''./3_start_eris.sh'' in the terminal with the open SSH connection to Eris from the home, ''/root'', directory of Eris.
[[Image:StartingRADA2nd.png|800px]]
=== Locating and retrieving log files ===
If you are only demoing the system there is no need to go beyond this point. Once you are done with a test that you want to compare to the model you should retrieve the log file right away so you don't mix it up with other test. On CO3050-11 go to the dircetory ''/home/shared/MainProject/Logs'' using the file browser (you can do this in a terminal but it is easier from the file explorer). Once there, look for the folder that has been modified most recently as Eris date is normally out of sync with its date and time. Then look for the newest log file. Log files are named like ''log(hh.mm.ss).txt'' (ex. log(13.04.51).txt). This naming convention works well to ensure that no log file is over written but it isn't useful of describing what the test was of or for. Copy this log to the Desktop or to a USB drive and rename it. A good method is to name the file something like ''RADA_ctrl_otherNote#.txt'', where Describes what system you tested (ex. RADA, RADA1D, PEN1D, PEN2D), what typ of controller was used, other notes and then a number if this is a repeat of another test. This is much more useful when looking back at these logs later on. Before transferring the log file for processing you should record the wheel and propeller battery voltages in the header of the log file. The log file format is both human readable and can be parsed by MATALB. It was designed by the first RADA Senior Design Team and more information about the log files can be found [http://wikis.ece.iastate.edu/robotic-agriculture-data-acquisition/index.php/Data_Analysis_Tool here.] See he section below on measuring battery voltage below in order to get the best measurements for simulation of RADA.
=== Measuring battery voltages ===
The last thing that you need to do before simulating an experiment of the RADA platform is record the battery voltages for both the wheels and propellers. The wheel battery can be measured unloaded as there isn't large line losses between the battery and the H-bridges. The propeller battery voltage needs to be measured under load because the power cord running up the pendulum has significant line losses at the currents the propellers draw when in use. The battery voltages can be recorded in the log file for the test. Open the log file for the test you just completed (Use KWrite for Linux machines or Notepad++ for Windows machines). The first few lines of the log is the headder. It should look like this:
#Constants pitch_P pitch_I pitch_D
#PIDValues 48000 18000 21000
#Constants roll_P roll_I roll_D
#PIDValues 48000 18000 21000
#Battery Vquad Vwheels
#Voltage
Follow the procedure for measuring the voltage of each battery and then record the voltage under the corresponding battery. Then save the log file and close out of your text editor and the test will be ready for processing. Recoding the battery voltages in this way makes it much easier to find if you need the value latter. The final log file header should look like this once you are done
#Constants pitch_P pitch_I pitch_D
#PIDValues 48000 18000 21000
#Constants roll_P roll_I roll_D
#PIDValues 48000 18000 21000
#Battery Vquad Vwheels
#Voltage 14.44 8.257
==== Wheel Battery ====
1. After test disconnect wheel battery from the system.
2. Measure voltage of battery using multimeter.
[[Image:MeasureVwheel.jpg|800px]]
You can use the plug used for charging the 2-cell Lipos but make sure to connect the plug to the multimeter before connecting the battery and disconnect the battery before disconnecting the plug from the mulitmeter. It is generally the best practice to give the multimeter a few minutes to allow for the voltage measurement to stabilize as the battery measurement tends to be a little low right after the test. The multimeter will report data out to four decimal places it is best just to round to three decimal places for the wheel voltage.
==== Quad Battery ====
1. Setup code to run all four propellers at 50% throttle, uncomment the definition of ''mot50'' in main.cpp and compile the project.
2. Power off propellers by turning off the switch to the ESCs.
3. Connect multimeter to measure the voltage across one of the ESCs. This is done by using the power splitter cord.
-Connect one of the female XT60 connectors on the splitter to a male XT60 connector to banana connector cable.
-The banana connector connect to the hand held multimeter. The multimeter should be set to the 20VDC measurement setting.
-Next unplug one the ESCs' power connection.
-reconnect the ESC to power through the two remain connectors on the spliter cable.
4. Power on the propellers.
5. Run the system at 50% throttle and measure the steady-state voltage during the test. The battery will slow the voltage decay significantly, meaning it will keep the same measurement for a few seconds.
6. Stop the test and record the voltage in the log file. Make sure to disconnect the batter before removing the splitter cable.
{| class="wikitable" style="text-align:center"
|-
| [[Image:PowerSplitter.jpg|200px]]
| [[Image:QuadMultiCon.jpg |200px]]
| [[Image:QuadMultiSet.JPG |200px]]
| [[Image:QuadMeasESCcon.JPG|200px]]
|-
| Splitter cord.
| Connect splitter to multimeter.
| Settings for multimeter.
| Connecting ESC through splitter.
|}
The testing setup should look like the image below:
[[Image:QuadBattMeas.jpg|800px]]
== Post processing and Simulation ==
Simulating a test of RADA starts with processing and storing the data. Then all of the parameters of the model are loaded in the MATLAB Workspace. Finally the Simulink file used for the simulation is opened and the length of the simulation is set to match the length of the actual test. The simulation is run and the simulation output is stored. Finally the data should be plotted and compared.
=== Using the MATLAB data parsing tool ===
In depth discussion of how to use the log file parsing tool is described [http://wikis.ece.iastate.edu/robotic-agriculture-data-acquisition/index.php/Data_Analysis_Tool here.] I suggest using the version of the tool in the rada_resarch_project git repository Paul Uhing used for his Master's research. It con be found on CO3050-11 under the ucart account in the directory ''~/rada_research_project/DataAnalysiTool_omnicoor/Tool''. Simply open MATLAB and set the working directory to this file path. In the MATLAB Command Prompt run ''DataAnalysis''. A popup window should open up. Select the log file you want to process and wait for the tool to finish processing the file. Once this is complete there should be four structures in the MATLAB workspace.
-'''main''' : This contains all of the data extracted from the log file and the processing parameters used. main.expData contains two time structures: Time is used for the pendulum data and Eris_time is used for the ground vehicle data.
-'''X_ref''' : This contains the reference vector in m/s for x velocity that is feed into Simulink. This expedites the simulation setup process, this used to be done by hand.
-'''Y_ref''' : This contains the reference vector in m/s for y velocity that is feed into Simulink. This expedites the simulation setup process, this used to be done by hand.
-'''Yaw_ref''' : This contains the reference vector in radians for yaw that is feed into Simulink. This expedites the simulation setup process, this used to be done by hand. This one is new incase people start testing the system with heading changes but is not used in the current setup.
The first thing you should do is rename the main structure to the name you used for the log file. This is helpful for comparing multiple tests. Next you will want to crate two new variable ''Vquad_test'' an Vw_test''. In the MATLAB Command Prompt set the measured propeller voltage from the log file to ''Vquad_test'' and set the measured the wheel voltage to ''Vw_test'' as this will be used by the simulation. Finally if you did an open-loop test of the wheels create the variable ''Uol'' and set it to the open-loop wheel command used. Save all of these variables from the MATLAB workspace to a ''.mat'' file of the same name as log file you extracted the data from and save it in the same directory as your RADA Simulink files. As of August 2nd, 2016 this directory is ''~/rada_research_project/MATLAB/RADA.''
=== Setting up the MATLAB workspace for simulation ===
Change your MATLAB directory to this directory. Then run the simulation setup files. Currently you just need to run ''modelParams_smallWheels_RADA'' in the MATLAB Command Prompt. Next open the Simulink file with that contains the model of RADA controlled by the controller you tested.
-'''RADA_psiCtrl_v2_lqi_est.slx''' contains LQI, LQI+estimation, and LQG controller simulations.
-'''RADA_psiCtrl_v2.slx''' contains the PID controlled system.
-'''RADA_psiCtrl_v2_LQGsep.slx''' contains the subsystem LQG controlled system.
-'''RADA_psiCtrl_v2_LQGsep_ol.slx''' contains the simulation of the pendulum system controlled by an LQG and Eris controlled with open-loop commands.
Note all of the current (August 2nd, 2016) ''.slx'' files were created in MATLAB 2014b and will only work in MATLAB 2014B or newer. Then in the MATLAB Command Prompt type ''X_ref.time(end)'' exactly, don't add a semicolon, and hit enter. MATLAB will print the time of the last command in the X_ref structure. Set the en time of the simulation to this value and save your Simulink file.
=== Running simulations and storing results ===
Before running the simulation make sure that the simuation is using the ''ode23t'' differential equations solver. This system is a moderately stiff system of differential and the ''ode45'' solver doesn't do well with these types of systems. When using ''ode23t'' is should only take a few minutes to run a 100+ second simulation while doing the same test using ''ode45'' could take 8 hours. While this slow it is also bad for your hard drive as the simulation has to page between RAM and your computers hard drive a lot.
Once this check is done run the simulation. While it is running check what the output structures variables are named for for your RADA test system. Once the simulation is done go to your MATLAB Workspace and select all 15 outputs for your simulation or your sub-simulation if you used '''RADA_psiCtrl_v2_lqi_est.slx'''. Save these 15 output structures to a ''.mat'' file named as the log file with _sim appended to the end of the name.
The 15 outputs are structures containing a time vector and then the data from the simulation sampled at 100 Hz and the units of this data are the SI units (ex: radians, m/s). There is one output structure for x velocity, y velocity, x body velocity, y body velocity, theta (pitch), phi (roll), psi (yaw), and one per actuator command (ex: the command sent to a wheel). Now you have all the data you can plot it.
=== Plotting results ===
If you look at the ''DataSets'' folder below ''~/rada_research_project/MATLAB/RADA'' directory there are plenty of examples of how Paul Uhing compared simulation to test data. Generally you should grate a ''.m'' file with the same name as the log file this data was extracted from with _plot appended to the name.
Generally you can just copy an for RADA_LQG_compPID_plot.m RADA_PID_compLQG_plot.m, RADA_LQG_sep_plot.m, or RADA_LQG_sep_ol_plot.m files and rename the structures for your test.
These files create four figures. Figure 1 plots compares the x velocity data in the first sub figure and compares pitch (theta) data in the second sub figure. Figure 2 does the same thing as Figure 1 but with y velocity and roll data. Figure 3 looks at the yaw data. Finally, Figure 4 looks at the sample period between UAV and ERIS packets from the camera system just to check for periods of time with large packet drops.
You can follow a similar pattern to compare motor commands. Just make sure that you compare Quad Motor 2 from the test data with Quad Motor 4 from simulation and vise versa because propellers 2 and 4 were switch in Eris's software compared to the Model.
That is all you need to know for testing RADA against the model.
a84e4b6da08525c8302bcc04053dba14227adf92
328
318
2016-09-21T14:33:07Z
Jonessk
7
/* Setting Up a RADA Test */
wikitext
text/x-wiki
This page will take you though setting up and testing RADA, retrieving the log file and other necessary data to run a simulation of that test and processing the data in MATLAB. Then actually running the simulation of RADA in Simulink. The initial setup and how to test the system can also be applied to demoing RADA.
== Setting Up a RADA Test ==
Testing RADA is not overly difficult once you get the hang of the steps to setup RADA. The following steps may seem like a long process to go from starting the testing process to having completed simulation and plotting of the test results but this whole test procedure (with the exception of battery charging) can be completed in about 15-20 minutes. These steps are meant to be as detailed as possible in order to help new users of RADA get up and running as quickly as possible.
'''<span style="color:red">NOTE: Always run RADA with at least 2 people!</span>''' The pendulum arm can crash into the ground if the network starts to drop packets and one person cannot give commands to RADA and spot the pendulum. This is a safety issue for both you and the RADA platform.
=== Charging batteries ===
The lab currently uses mostly Hyperion batteries. We charge our batteries with a Hyperion EOS 1420i Net3 battery charger. For some general information about how to use this charger see [https://www.youtube.com/watch?v=-ox3EpzvsJ8 this video.]. In the lab we power this charger using the old Kepco Power supply because it is the only power supply that can supply enough current. Make sure that the power supply is set to an output voltage between 10.5V-29V.
{| class="wikitable" style="text-align:center"
|-
| [[Image:ChargerPowerSupplyOff.JPG|400px]]
| [[Image:ChargerPowerSuplyOn.JPG|400px]]
|-
| Kepco Power Supply off.
| Kepco Power Supply on with correct voltage supply range.
|}
The YouTube video link above should explain how to use the charger. RADA currently uses three different Lithium polymer (Lipo) batteries: 1600 mAh 2-cell Lipo for the wheels, 2600 mAh 2-cell Lipo for the electronics of Eris, and a 2600 mAh 4-cell Lipo for the propellers. The 1600 mAh 2-cell Lipo can be charged using memory slot 2 of the charger. The 2600 mAh 2-cell Lipos can be charged using memory slot 3 for fast charging and memory slot 4 for slower charging (use this if the battery voltage drops really low for 10-20 minutes then switch to fast charging). The 2600 mAh 4-cell Lipo can be charged using memory slot 8. The 1600 mAh 2-cell and 2600 mAh 4-cell generally charge in 10-20 minutes apiece while the 2600 mAh 2-cell generally take up to 70 minutes to charge fully.
=== Setting up the Camera System ===
The camera system is run on the windows computer CO3050-07. You can log into this computer using a local microcart username and password (not posted here for security reasons, but any one who works in the lab should know it). Once logged in, look for Tracking Tools in the start menu or look for the shortcut shown below:
[[Image:TrackingTools_shortcut.PNG|thumb|center|Tracking Tools shortcut]]
Once the program opens the screen should look something like this:
[[Image:NewTrackingTools.PNG|800px]]
In the Tracking Tools Quick Start pop up menu select Open Existing Project and then navigate to ''D:\Optitrack_Configuration'' (It should open to this directory by default) and select the most recent Tracking Tools project. It should have the naming scheme ''TrackingToolsProject YYYY-MM-DD timeStamp.ttp''. This is normally the most recently edited file when sorting by date modified. The most recent one as of August 1st, 2016 is ''TrackingToolsProject 2015-09-23 2.30pm.ttp''.
[[Image:OpeningProject.PNG|800px]]
You should notice that the cameras shown in the main project screen arrange themselves like the camera system configuration once the project has been opened. Now the constellations need to be loaded. This can be done by going to ''File->Open'' and another popup window will open. Navigate back to ''D:\Optitrack_Configuration'' (It should open to this directory by default) and select the most recently dated set of RADA trackables. They have the naming scheme ''RADA_entireSystem_M_D_YYYY.tra''. The most recent one as of August 1st, 2016 is ''RADA_entireSystem_7_8_2016.tra''.
[[Image:Opening_trackables.PNG|800px]]
Once the project and trackables are open, the cameras should appear in their constellation (square) and there should be two constellations under ''Project Explorer->Trackables''. One named UAV for the pendulum and one named ERIS for the ground vehicle. In order to get additional information about each constellation, left click on the the name of the desired trackable.
[[Image:SelectingUAV.PNG|800px]]
Once a trackable is selected more information about it is available in the ''Trackables'' Tab on the right side of the screen. For the current position and orientation look at the ''Real-Time Info'' sub-tab. This gives the orientation in the wrong order for how we currently use the Euler angles. When two or three of the angles are near zero you can switch yaw and pitch to get roughly the correct orientation.
[[Image:Uav_realTimeInfo.PNG|800px]]
Now we need check to make sure the system is zeroed.
1. Hold RADA so that the front of the ground robot (ERIS is facing the wall with the white boards (east)). The front side of Eris is labeled. If it isn't, the front is the side opposite the switches and the side with the trackable constellation on it.
2. Make sure that the motor with the red motor mount is also facing the wall with the white boards.
3. Make sure the quad system is aligned along Eris Axis by standing behind the system. If the system is aligned, you should be able to block the mounting bolts of the front propeller motor with the pole while facing the east wall.
4. While holding the pendulum approximately vertical, see if the camera system reads zeros for the pendulum (UAV) pitch and roll (yaw and roll in ''Real-Time Info''). If yaw is off by a few degrees that is fine.
5. Compare the yaw of the UAV to that of ERIS (Remember this is pitch in ''Real-Time Info''). If they are both near zero and within a few degrees and the pendulum's pitch/roll were also near zero then you are ready to use the camera system. Otherwise, go to the next step.
6. You need to zero the pendulum.
- Align ERIS so it is near zero yaw first (eye ball it).
- Get a level and a friend. Have your friend use a level to ensure that the pendulum is level in both directions and hold it there.
- With the UAV constellation selected go to the ''Orientation'' tab (next to ''Real-Time Info'' tab) and click on ''Reset To Current Orientation button''
- Now your friend can set the pendulum down and you can zero ERIS the same way.
7. Save the new trackable orientation by going to ''File->Save Trackables...'' and save a file using the same naming conventions as the trackable file you opened earlier. Use the current data so you don't have to re-zero the system the next time you test.
[[Image:Uav_ResetOrientation.PNG|800px]]
=== Building Software ===
The development environment for running RADA is hosted on CO3050-11, a Linux Red Hat environment. This computer has a local ucart user name that you should use. The password isn't put here for security reasons. In order to ensure that the RADA software is setup correctly for the test you want to run. To do this you will need to open the main.cpp and logger.cpp files and make sure all of the compile time macros you want are defined correctly. All of the c++ files you should need to edit are in the directory ''~/Desktop/rada_research_project/ErisResearchCode/CppProjects/MainProgram_PacketLoss/src/Korebot'' Below is a compiler macro options for main.cpp:
-'''H2ctrl''' : This will cause the system to enter H2 controller mode where the whole RADA system is controlled by an H2 controller.
-'''ssTracking''' : H2ctrl must also be defined for this macro to do anything. This macro will has the system to be controlled by a tracking H2 controller.
-'''ssMotors''' : H2ctrl must also be defined for this macro to do anything. This macro will has the system to be controlled by an H2 contorller that contains propeller states. This also cause the system to "Dance."
-'''ssDrop''' : Cause the system to go into packet drop controller mode. This mode allows controllers designed for lossy networks to be tested. Based off of other definitions how lossy the network is can be simulated. If nothing else is defined this controller becomes basically a H2 controller.
-'''drop10''' : Will put the packet drop mode into 10% loss mode and use a controller designed for 10% loss.
-'''drop30''' : Will put the packet drop mode into 30% loss mode and use a controller designed for 30% loss.
-'''drop50''' : Will put the packet drop mode into 50% loss mode and use a controller designed for 50% loss.
-'''mot50''' : This macro over-rides all other macros. If this is turned on the wheels will not run and the propllers will be run at 50% command. This is used for measuring the effective battery voltage seen by the ESCs. This is always run after a test.
-'''RADAlqi''' : This macro will cause the system to use an LQI controller on the whole system. The linear velocity states are calculated with no filter and the angular velocity states are calculated with filters.
-'''RADAlqi_est''' : This macro will cause the system to use an LQI controller on the whole system. A traditional estimator is used to estimate the states.
-'''rada_lqg''' : This macro will cause the entire system to be controlled by a LQG controller/estimator system.
-'''rada_split_lqg''' : This macro will cause the pendulum and ground robot to be controlled by their own LQG systems.
-'''rada_split_lqg_ol''' : This macro will cause the pendulum to be controlled by an LQG controller, the yaw of the ground robot to be controlled by a PID controller, and the ground robot linear velocities to be controlled with open-loop commands.
-'''yaw_off''' : This macro will cause the yaw control to be disabled on some controllers.
*'''accR''' : This macro will cause the PID linear velocity controllers to be given ramps to acclerate from one velocity to another instead of steps.
-'''posRamp''' : This macro will cause the linear velocities of RADA to be controlled by position PIDs with ramp reference instead of velocity commands.
-If no controller selection is made all controllers revert to PID controllers
All of these macros can be defined simply by uncommenting the corresponding define statement in main.cpp. The macros in the logger.cpp can be seen below:
-'''ssDrop''' : This macro puts the logger into packed drop controller mode and logs the correct values for the packet drop controllers.
-'''RADAlqi''' : This macro puts the logger into full system LQI controller logging mode.
-'''RADAlqi_est''' : This macro puts the logger into full system LQI controller plus estimator logging mode.
-'''rada_lqg''' : This puts the logger into full system LQG controller logging mode.
-'''rada_split_lqg''' : This macro causes the logger to log data about the subsystem LQG controllers.
-'''rada_split_lqg_ol''' : This cause the system to log data about the pendulum LQG system and the open-loop linear velocity commands.
-'''H2ctrl''' : This macro causes the logger to log data about the full system H2 controllers.
-If no logging mode is selected then the logger will default to logging PID data.
Because the system only calculates controllers for one set of controllers it is important to ensure that the logger is in the correct mode based off of what is defined in main.cpp. As of August 1st, 2016 the defines in main.cpp are not seen in logger.cpp.
Finally in a command prompt navigate to the driectroy: ''~/Desktop/rada_research_project/ErisResearchCode/CppProjects/MainProgram_PacketLoss''
Here just type: ''make''. The code will compile for your desired mode. For setting up a new development directory see [http://wikis.ece.iastate.edu/robotic-agriculture-data-acquisition/index.php/Setting_up_a_new_development_environment Setting up a new development environment] from the RADA senior Design wiki.
[[Image:ComplingRADACode.png|800px]]
The complied executable code ends up in ''/home/shared/MainProject''. The ''/home/shared'' directory is setup as a network file share (NFS).
[[Image:ErisCompliedCode-config.png|800px]]
This service needs to be restarted when CO3050-11 is restarted. [http://wikis.ece.iastate.edu/robotic-agriculture-data-acquisition/index.php/Configuring_NFS_shares_for_the_robot Configure NFS shares for the robot] from the RADA Senior Design wiki. Be sure to use the new Linux install command in step six. Though I have fond that even on a good strt the ''[ok]'' messages will still print.
=== Turing on RADA ===
Turing on Eris is fairly simple. Each system has its own battery. There is one for the wheels that plugs in at the front of Eris (opposite side of the swiches), one for the electronics in the back of Eris (in between the switches), and one for the propellers that goes on top of Eris.
[[Image:ErisOnPhoto.jpg|800px]]
The wheel battery is normally 1600 mAh 2-cell Lipo but any 2-cell Lipo will work. The wheels are turned on by flipping the silver switch so the top points away from the system. The electronics normally use a 2600 mAh 2-cell Lipo. The electronics are turned on by flipping the green switch away from the system. It is important that you only the WIFI adapter or Ethernet plugged in at the same time or VRPN my listen to the camera data broadcast over both connects which could cause problems. The propeller system is powered via a 2600 mAh 4-cell Lipo that connects to a power cable at the base of the pendulum. There is a switch to turn on the power to the propellers system. You will know it is on when the 1 on the switch is flush with the switch housing instead of sticking out. It takes about 30 seconds to a minute for Eris to boot up and start the networking connections. When the WIFI is plugged in you will know it is ready when a blue light turns on, on the module.
=== Connecting to RADA ===
RADA is controlled through an SSH connection. in a commands prompt, not the one you compile the code from so that you can recompile for different setup with out needing to close the connection. If you are using a WIFI connect use the command ''ssh root@192.168.0.53''. If you are connected to Eris through a LAN connaction use the command ''ssh root@192.168.0.54''. If the connection goes though you should be proped for a password.
The password is ''rootme''.
[[Image:Ssh2Eris.png|800px]]
It is important to close the SSH connection before turning off Eris because the terminal you are using will hang up if you don't. You can close the connection by using the command ''exit''.
[[Image:ClosingSSH.png|800px]]
== Testing RADA ==
Now that you are connected to Eris you can run tests. The testing is started by a few different methods.
=== Running the first test after power up ===
For the firs test after powering on Eris a few additional steps need to be completed in order to test the system. The FPGA motor controller needs to be programmed and Eris needs to connect the the NFS server running on CO3050-11. This is accomplished by running ''1_co3050-11.sh'', this shell scrip will setup the NFS, load the bit file into the FPGA configuration memory. Then it retrieves the executable file from the NFS server ''/mnt/nfs/MainProject and runs the executable. Once the user exits the executable the log file produces is copied from the ''~/Logs/YYYY_MM_DD_Day'' directory on Eris to ''/home/shared/MainProject/Logs/YYYY_MM_DD_Day'' on CO3050-11. When the folder for the current Eris date doesn't exist it creates this directory in CO3050-11 and then removes the directory and log file from Eris. You may see an warning that when coping the log file Eris couldn't maintain the file permisiion settings. This is normal as Eris doesn't have the same access to the NSF server as it has to its own files. This Date stamp uses date on Eris which is currently in June of 2008 as of August 2nd, 2016.
Before starting the test it is best to have someone spotting the pendulum a holding it near vertical so that the pendulum doesn't have issues when entering a control mode.'''<span style="color:red"> Always run ensure the pendulum is spotted by a second person when testing so you don't hurt yourself, others in the lab, or the RADA system.</span>''' Once you spotter is ready run the shell scrip by= using the command ''./1_co3050-11.sh'' in the terminal with the open SSH connection to Eris from the home, ''/root'', directory of Eris. When you run this script there will be a bunch of information printed out about the PIC bus and loading the bit file to configure the FPGA, you will know that RADA is ready for the test when it asks you to select a running mode. See the Testing Modes section below. This script can take a while to complete so beyond the first test after start up you don't need to run this script. See the Section about Running additional tests below.
[[Image:StartingRADA initial.png|800px]]
=== Testing Modes ===
The RADA system has three testing modes: Robot Control Mode, Tuning Mode, and Box Step Mode. Additionally you can exit the execution at any time by pressing the ''Esc'' key. Once the terminal asks you to chose a mode you can use the following commands to enter the desired mode with a three second delay or exit the program. You can also use these commands to switch between the modes.
-''v'' : Enters the pendulum PID tuning mode, this will only really work when using PIDs to control the pendulum.
-''b'' : Enter Robot control mode, in this mode you can drive the robot around and the pendulum will try to stay vertical. This is the main mode used for testing the whole RADA system.
-''n'' : Enters box step mode, where the pendulum will change its desired pitch and roll angles every 20 seconds and move in a box shape.
-''Esc'' : By hitting the escape key the program will exit the program.
You will almost always want to run Robot Control Mode as the other modes are legacy modes from when we initially built and tested RADA and only works with the pendulum PID controllers. There are also a few utility commands that can be used in all modes.
-''2'' : Resets I composts of the Pitch/Roll PIDs and only the PIDs.
-''m'' : Adds a marker to the Log file incase odd things happen somewhere. This just increments a counter so if you use it look for changes in the marker value.
==== Robot Control Model ====
In Robot control mode you can control the motion of Eris. For PID control of Eris or 1D state feedback system the directional commands command Eris body velocity were for full system and Eris system state feedback controllers control the global velocity. All of these keys only need to be pressed not held down.
-''w'' : Moves Eris forward (+x) at some velocity depending on the controller.
-''s'' : Moves Eris in reverse (-x) at some velocity depending on the controller.
-''d'' : Moves Eris in right (+y) at some velocity depending on the controller.
-''a'' : Moves Eris in left (-y) at some velocity depending on the controller.
-''p'' : Stops the motion of Eris (Set all velocity set points to zero). I.e. if you hit ''w'' then hit ''s'' then Eris will be moving in reverse.
-''y'' : Moves Eris forward and to the right (+x/+y) simultaneously at some velocity depending on the controller.
-''t'' : Moves Eris forward and to the left (+x/-y) simultaneously at some velocity depending on the controller.
-''i'' : Moves Eris reverse and to the right (-x/+y) simultaneously at some velocity depending on the controller.
-''y'' : Moves Eris reverse and to the left (-x/-y) simultaneously at some velocity depending on the controller.
-''e'' : Rotate Eris clockwise (+yaw) at some angular rate. This only worked when RADA used the closed-loop FPGA control of the wheels. There is currently no controllers that use this command.
-''q'' : Rotate Eris counter-clockwise (-yaw) at some angular rate. This only worked when RADA used the closed-loop FPGA control of the wheels. There is currently no controllers that use this command.
-''<'' : Increment Eris' desired heading 45 degrees counter-clockwise (-yaw).
-''>'' : Increment Eris' desired heading 45 degrees clockwise (+yaw).
-''7'' : Increments the pitch set point (+pitch).
-''4'' : Decrements the pitch set point (-pitch).
-''8'' : Increments the roll set point (+roll).
-''5'' : Decrements the roll set point (-roll).
==== Tuning Mode ====
Tuning mode allows you to tune the PID controllers for both pitch and roll. The UI commands here are also available in Box Step Mode.
-''1'' : Tune the Pitch PID.
-''3'' : Tune the Roll PID.
-''7'' : Increase proportional gain of PID being tuned.
-''4'' : Decrease proportional gain of PID being tuned.
-''8'' : Increase integral gain of PID being tuned.
-''5'' : Decrease integral gain of PID being tuned.
-''9'' : Increase derivative gain of PID being tuned.
-''6'' : Decrease derivative gain of PID being tuned.
-''i'' : Increase set point of PID being tuned.
-''k'' : Decrease set point of PID being tuned.
-''o'' : Increase integral windup term of PID being tuned. (Not used)
-''l'' : Decrease integral windup term of PID being tuned. (Not used)
==== Box Step Mode ====
Box set mode will automatically change the set points of the pendulum every 20 seconds. The case statement for this mode can be changed for 1D and 2D step modes. This mode allows the user to use he same commands as Tuning Mode.
=== Running additional Tests ===
Once you have run one test with Eris on it is unnecessary to configure the FPGA or connect to the NFS server again. This is what took much of the time in the initial setup. This is what the script ''3_stat_eris.sh'' was developed for. It does everything that ''1_co3050-11.sh'' does but without reprogramming the FPGA or reconnecting to the NFS server. As a result it is ready to test much quicker.
Before starting the test it is best to have someone spotting the pendulum a holding it near vertical so that the pendulum doesn't have issues when entering a control mode.'''<span style="color:red"> Always run ensure the pendulum is spotted by a second person when testing so you don't hurt yourself, others in the lab, or the RADA system.</span>''' Once you spotter is ready run the shell scrip by= using the command ''./3_start_eris.sh'' in the terminal with the open SSH connection to Eris from the home, ''/root'', directory of Eris.
[[Image:StartingRADA2nd.png|800px]]
=== Locating and retrieving log files ===
If you are only demoing the system there is no need to go beyond this point. Once you are done with a test that you want to compare to the model you should retrieve the log file right away so you don't mix it up with other test. On CO3050-11 go to the dircetory ''/home/shared/MainProject/Logs'' using the file browser (you can do this in a terminal but it is easier from the file explorer). Once there, look for the folder that has been modified most recently as Eris date is normally out of sync with its date and time. Then look for the newest log file. Log files are named like ''log(hh.mm.ss).txt'' (ex. log(13.04.51).txt). This naming convention works well to ensure that no log file is over written but it isn't useful of describing what the test was of or for. Copy this log to the Desktop or to a USB drive and rename it. A good method is to name the file something like ''RADA_ctrl_otherNote#.txt'', where Describes what system you tested (ex. RADA, RADA1D, PEN1D, PEN2D), what typ of controller was used, other notes and then a number if this is a repeat of another test. This is much more useful when looking back at these logs later on. Before transferring the log file for processing you should record the wheel and propeller battery voltages in the header of the log file. The log file format is both human readable and can be parsed by MATALB. It was designed by the first RADA Senior Design Team and more information about the log files can be found [http://wikis.ece.iastate.edu/robotic-agriculture-data-acquisition/index.php/Data_Analysis_Tool here.] See he section below on measuring battery voltage below in order to get the best measurements for simulation of RADA.
=== Measuring battery voltages ===
The last thing that you need to do before simulating an experiment of the RADA platform is record the battery voltages for both the wheels and propellers. The wheel battery can be measured unloaded as there isn't large line losses between the battery and the H-bridges. The propeller battery voltage needs to be measured under load because the power cord running up the pendulum has significant line losses at the currents the propellers draw when in use. The battery voltages can be recorded in the log file for the test. Open the log file for the test you just completed (Use KWrite for Linux machines or Notepad++ for Windows machines). The first few lines of the log is the headder. It should look like this:
#Constants pitch_P pitch_I pitch_D
#PIDValues 48000 18000 21000
#Constants roll_P roll_I roll_D
#PIDValues 48000 18000 21000
#Battery Vquad Vwheels
#Voltage
Follow the procedure for measuring the voltage of each battery and then record the voltage under the corresponding battery. Then save the log file and close out of your text editor and the test will be ready for processing. Recoding the battery voltages in this way makes it much easier to find if you need the value latter. The final log file header should look like this once you are done
#Constants pitch_P pitch_I pitch_D
#PIDValues 48000 18000 21000
#Constants roll_P roll_I roll_D
#PIDValues 48000 18000 21000
#Battery Vquad Vwheels
#Voltage 14.44 8.257
==== Wheel Battery ====
1. After test disconnect wheel battery from the system.
2. Measure voltage of battery using multimeter.
[[Image:MeasureVwheel.jpg|800px]]
You can use the plug used for charging the 2-cell Lipos but make sure to connect the plug to the multimeter before connecting the battery and disconnect the battery before disconnecting the plug from the mulitmeter. It is generally the best practice to give the multimeter a few minutes to allow for the voltage measurement to stabilize as the battery measurement tends to be a little low right after the test. The multimeter will report data out to four decimal places it is best just to round to three decimal places for the wheel voltage.
==== Quad Battery ====
1. Setup code to run all four propellers at 50% throttle, uncomment the definition of ''mot50'' in main.cpp and compile the project.
2. Power off propellers by turning off the switch to the ESCs.
3. Connect multimeter to measure the voltage across one of the ESCs. This is done by using the power splitter cord.
-Connect one of the female XT60 connectors on the splitter to a male XT60 connector to banana connector cable.
-The banana connector connect to the hand held multimeter. The multimeter should be set to the 20VDC measurement setting.
-Next unplug one the ESCs' power connection.
-reconnect the ESC to power through the two remain connectors on the spliter cable.
4. Power on the propellers.
5. Run the system at 50% throttle and measure the steady-state voltage during the test. The battery will slow the voltage decay significantly, meaning it will keep the same measurement for a few seconds.
6. Stop the test and record the voltage in the log file. Make sure to disconnect the batter before removing the splitter cable.
{| class="wikitable" style="text-align:center"
|-
| [[Image:PowerSplitter.jpg|200px]]
| [[Image:QuadMultiCon.jpg |200px]]
| [[Image:QuadMultiSet.JPG |200px]]
| [[Image:QuadMeasESCcon.JPG|200px]]
|-
| Splitter cord.
| Connect splitter to multimeter.
| Settings for multimeter.
| Connecting ESC through splitter.
|}
The testing setup should look like the image below:
[[Image:QuadBattMeas.jpg|800px]]
== Post processing and Simulation ==
Simulating a test of RADA starts with processing and storing the data. Then all of the parameters of the model are loaded in the MATLAB Workspace. Finally the Simulink file used for the simulation is opened and the length of the simulation is set to match the length of the actual test. The simulation is run and the simulation output is stored. Finally the data should be plotted and compared.
=== Using the MATLAB data parsing tool ===
In depth discussion of how to use the log file parsing tool is described [http://wikis.ece.iastate.edu/robotic-agriculture-data-acquisition/index.php/Data_Analysis_Tool here.] I suggest using the version of the tool in the rada_resarch_project git repository Paul Uhing used for his Master's research. It con be found on CO3050-11 under the ucart account in the directory ''~/rada_research_project/DataAnalysiTool_omnicoor/Tool''. Simply open MATLAB and set the working directory to this file path. In the MATLAB Command Prompt run ''DataAnalysis''. A popup window should open up. Select the log file you want to process and wait for the tool to finish processing the file. Once this is complete there should be four structures in the MATLAB workspace.
-'''main''' : This contains all of the data extracted from the log file and the processing parameters used. main.expData contains two time structures: Time is used for the pendulum data and Eris_time is used for the ground vehicle data.
-'''X_ref''' : This contains the reference vector in m/s for x velocity that is feed into Simulink. This expedites the simulation setup process, this used to be done by hand.
-'''Y_ref''' : This contains the reference vector in m/s for y velocity that is feed into Simulink. This expedites the simulation setup process, this used to be done by hand.
-'''Yaw_ref''' : This contains the reference vector in radians for yaw that is feed into Simulink. This expedites the simulation setup process, this used to be done by hand. This one is new incase people start testing the system with heading changes but is not used in the current setup.
The first thing you should do is rename the main structure to the name you used for the log file. This is helpful for comparing multiple tests. Next you will want to crate two new variable ''Vquad_test'' an Vw_test''. In the MATLAB Command Prompt set the measured propeller voltage from the log file to ''Vquad_test'' and set the measured the wheel voltage to ''Vw_test'' as this will be used by the simulation. Finally if you did an open-loop test of the wheels create the variable ''Uol'' and set it to the open-loop wheel command used. Save all of these variables from the MATLAB workspace to a ''.mat'' file of the same name as log file you extracted the data from and save it in the same directory as your RADA Simulink files. As of August 2nd, 2016 this directory is ''~/rada_research_project/MATLAB/RADA.''
=== Setting up the MATLAB workspace for simulation ===
Change your MATLAB directory to this directory. Then run the simulation setup files. Currently you just need to run ''modelParams_smallWheels_RADA'' in the MATLAB Command Prompt. Next open the Simulink file with that contains the model of RADA controlled by the controller you tested.
-'''RADA_psiCtrl_v2_lqi_est.slx''' contains LQI, LQI+estimation, and LQG controller simulations.
-'''RADA_psiCtrl_v2.slx''' contains the PID controlled system.
-'''RADA_psiCtrl_v2_LQGsep.slx''' contains the subsystem LQG controlled system.
-'''RADA_psiCtrl_v2_LQGsep_ol.slx''' contains the simulation of the pendulum system controlled by an LQG and Eris controlled with open-loop commands.
Note all of the current (August 2nd, 2016) ''.slx'' files were created in MATLAB 2014b and will only work in MATLAB 2014B or newer. Then in the MATLAB Command Prompt type ''X_ref.time(end)'' exactly, don't add a semicolon, and hit enter. MATLAB will print the time of the last command in the X_ref structure. Set the en time of the simulation to this value and save your Simulink file.
=== Running simulations and storing results ===
Before running the simulation make sure that the simuation is using the ''ode23t'' differential equations solver. This system is a moderately stiff system of differential and the ''ode45'' solver doesn't do well with these types of systems. When using ''ode23t'' is should only take a few minutes to run a 100+ second simulation while doing the same test using ''ode45'' could take 8 hours. While this slow it is also bad for your hard drive as the simulation has to page between RAM and your computers hard drive a lot.
Once this check is done run the simulation. While it is running check what the output structures variables are named for for your RADA test system. Once the simulation is done go to your MATLAB Workspace and select all 15 outputs for your simulation or your sub-simulation if you used '''RADA_psiCtrl_v2_lqi_est.slx'''. Save these 15 output structures to a ''.mat'' file named as the log file with _sim appended to the end of the name.
The 15 outputs are structures containing a time vector and then the data from the simulation sampled at 100 Hz and the units of this data are the SI units (ex: radians, m/s). There is one output structure for x velocity, y velocity, x body velocity, y body velocity, theta (pitch), phi (roll), psi (yaw), and one per actuator command (ex: the command sent to a wheel). Now you have all the data you can plot it.
=== Plotting results ===
If you look at the ''DataSets'' folder below ''~/rada_research_project/MATLAB/RADA'' directory there are plenty of examples of how Paul Uhing compared simulation to test data. Generally you should grate a ''.m'' file with the same name as the log file this data was extracted from with _plot appended to the name.
Generally you can just copy an for RADA_LQG_compPID_plot.m RADA_PID_compLQG_plot.m, RADA_LQG_sep_plot.m, or RADA_LQG_sep_ol_plot.m files and rename the structures for your test.
These files create four figures. Figure 1 plots compares the x velocity data in the first sub figure and compares pitch (theta) data in the second sub figure. Figure 2 does the same thing as Figure 1 but with y velocity and roll data. Figure 3 looks at the yaw data. Finally, Figure 4 looks at the sample period between UAV and ERIS packets from the camera system just to check for periods of time with large packet drops.
You can follow a similar pattern to compare motor commands. Just make sure that you compare Quad Motor 2 from the test data with Quad Motor 4 from simulation and vise versa because propellers 2 and 4 were switch in Eris's software compared to the Model.
That is all you need to know for testing RADA against the model.
0f903b6a65b039c1b5be27d27dd33b65a1a9b087
329
328
2016-09-21T14:33:35Z
Jonessk
7
/* Setting Up a RADA Test */
wikitext
text/x-wiki
This page will take you though setting up and testing RADA, retrieving the log file and other necessary data to run a simulation of that test and processing the data in MATLAB. Then actually running the simulation of RADA in Simulink. The initial setup and how to test the system can also be applied to demoing RADA.
== Setting Up a RADA Test ==
Testing RADA is not overly difficult once you get the hang of the steps to setup RADA. The following steps may seem like a long process to go from starting the testing process to having completed simulation and plotting of the test results but this whole test procedure (with the exception of battery charging) can be completed in about 15-20 minutes. These steps are meant to be as detailed as possible in order to help new users of RADA get up and running as quickly as possible.
'''<span style="color:red">NOTE: Always run RADA with at least 2 people!</span>''' The pendulum arm can crash into the ground if the network starts to drop packets and one person cannot give commands to RADA and spot the pendulum. This is a safety issue for both you and the RADA platform.
=== Charging Batteries ===
The lab currently uses mostly Hyperion batteries. We charge our batteries with a Hyperion EOS 1420i Net3 battery charger. For some general information about how to use this charger see [https://www.youtube.com/watch?v=-ox3EpzvsJ8 this video.]. In the lab we power this charger using the old Kepco Power supply because it is the only power supply that can supply enough current. Make sure that the power supply is set to an output voltage between 10.5V-29V.
{| class="wikitable" style="text-align:center"
|-
| [[Image:ChargerPowerSupplyOff.JPG|400px]]
| [[Image:ChargerPowerSuplyOn.JPG|400px]]
|-
| Kepco Power Supply off.
| Kepco Power Supply on with correct voltage supply range.
|}
The YouTube video link above should explain how to use the charger. RADA currently uses three different Lithium polymer (Lipo) batteries: 1600 mAh 2-cell Lipo for the wheels, 2600 mAh 2-cell Lipo for the electronics of Eris, and a 2600 mAh 4-cell Lipo for the propellers. The 1600 mAh 2-cell Lipo can be charged using memory slot 2 of the charger. The 2600 mAh 2-cell Lipos can be charged using memory slot 3 for fast charging and memory slot 4 for slower charging (use this if the battery voltage drops really low for 10-20 minutes then switch to fast charging). The 2600 mAh 4-cell Lipo can be charged using memory slot 8. The 1600 mAh 2-cell and 2600 mAh 4-cell generally charge in 10-20 minutes apiece while the 2600 mAh 2-cell generally take up to 70 minutes to charge fully.
=== Setting up the Camera System ===
The camera system is run on the windows computer CO3050-07. You can log into this computer using a local microcart username and password (not posted here for security reasons, but any one who works in the lab should know it). Once logged in, look for Tracking Tools in the start menu or look for the shortcut shown below:
[[Image:TrackingTools_shortcut.PNG|thumb|center|Tracking Tools shortcut]]
Once the program opens the screen should look something like this:
[[Image:NewTrackingTools.PNG|800px]]
In the Tracking Tools Quick Start pop up menu select Open Existing Project and then navigate to ''D:\Optitrack_Configuration'' (It should open to this directory by default) and select the most recent Tracking Tools project. It should have the naming scheme ''TrackingToolsProject YYYY-MM-DD timeStamp.ttp''. This is normally the most recently edited file when sorting by date modified. The most recent one as of August 1st, 2016 is ''TrackingToolsProject 2015-09-23 2.30pm.ttp''.
[[Image:OpeningProject.PNG|800px]]
You should notice that the cameras shown in the main project screen arrange themselves like the camera system configuration once the project has been opened. Now the constellations need to be loaded. This can be done by going to ''File->Open'' and another popup window will open. Navigate back to ''D:\Optitrack_Configuration'' (It should open to this directory by default) and select the most recently dated set of RADA trackables. They have the naming scheme ''RADA_entireSystem_M_D_YYYY.tra''. The most recent one as of August 1st, 2016 is ''RADA_entireSystem_7_8_2016.tra''.
[[Image:Opening_trackables.PNG|800px]]
Once the project and trackables are open, the cameras should appear in their constellation (square) and there should be two constellations under ''Project Explorer->Trackables''. One named UAV for the pendulum and one named ERIS for the ground vehicle. In order to get additional information about each constellation, left click on the the name of the desired trackable.
[[Image:SelectingUAV.PNG|800px]]
Once a trackable is selected more information about it is available in the ''Trackables'' Tab on the right side of the screen. For the current position and orientation look at the ''Real-Time Info'' sub-tab. This gives the orientation in the wrong order for how we currently use the Euler angles. When two or three of the angles are near zero you can switch yaw and pitch to get roughly the correct orientation.
[[Image:Uav_realTimeInfo.PNG|800px]]
Now we need check to make sure the system is zeroed.
1. Hold RADA so that the front of the ground robot (ERIS is facing the wall with the white boards (east)). The front side of Eris is labeled. If it isn't, the front is the side opposite the switches and the side with the trackable constellation on it.
2. Make sure that the motor with the red motor mount is also facing the wall with the white boards.
3. Make sure the quad system is aligned along Eris Axis by standing behind the system. If the system is aligned, you should be able to block the mounting bolts of the front propeller motor with the pole while facing the east wall.
4. While holding the pendulum approximately vertical, see if the camera system reads zeros for the pendulum (UAV) pitch and roll (yaw and roll in ''Real-Time Info''). If yaw is off by a few degrees that is fine.
5. Compare the yaw of the UAV to that of ERIS (Remember this is pitch in ''Real-Time Info''). If they are both near zero and within a few degrees and the pendulum's pitch/roll were also near zero then you are ready to use the camera system. Otherwise, go to the next step.
6. You need to zero the pendulum.
- Align ERIS so it is near zero yaw first (eye ball it).
- Get a level and a friend. Have your friend use a level to ensure that the pendulum is level in both directions and hold it there.
- With the UAV constellation selected go to the ''Orientation'' tab (next to ''Real-Time Info'' tab) and click on ''Reset To Current Orientation button''
- Now your friend can set the pendulum down and you can zero ERIS the same way.
7. Save the new trackable orientation by going to ''File->Save Trackables...'' and save a file using the same naming conventions as the trackable file you opened earlier. Use the current data so you don't have to re-zero the system the next time you test.
[[Image:Uav_ResetOrientation.PNG|800px]]
=== Building Software ===
The development environment for running RADA is hosted on CO3050-11, a Linux Red Hat environment. This computer has a local ucart user name that you should use. The password isn't put here for security reasons. In order to ensure that the RADA software is setup correctly for the test you want to run. To do this you will need to open the main.cpp and logger.cpp files and make sure all of the compile time macros you want are defined correctly. All of the c++ files you should need to edit are in the directory ''~/Desktop/rada_research_project/ErisResearchCode/CppProjects/MainProgram_PacketLoss/src/Korebot'' Below is a compiler macro options for main.cpp:
-'''H2ctrl''' : This will cause the system to enter H2 controller mode where the whole RADA system is controlled by an H2 controller.
-'''ssTracking''' : H2ctrl must also be defined for this macro to do anything. This macro will has the system to be controlled by a tracking H2 controller.
-'''ssMotors''' : H2ctrl must also be defined for this macro to do anything. This macro will has the system to be controlled by an H2 contorller that contains propeller states. This also cause the system to "Dance."
-'''ssDrop''' : Cause the system to go into packet drop controller mode. This mode allows controllers designed for lossy networks to be tested. Based off of other definitions how lossy the network is can be simulated. If nothing else is defined this controller becomes basically a H2 controller.
-'''drop10''' : Will put the packet drop mode into 10% loss mode and use a controller designed for 10% loss.
-'''drop30''' : Will put the packet drop mode into 30% loss mode and use a controller designed for 30% loss.
-'''drop50''' : Will put the packet drop mode into 50% loss mode and use a controller designed for 50% loss.
-'''mot50''' : This macro over-rides all other macros. If this is turned on the wheels will not run and the propllers will be run at 50% command. This is used for measuring the effective battery voltage seen by the ESCs. This is always run after a test.
-'''RADAlqi''' : This macro will cause the system to use an LQI controller on the whole system. The linear velocity states are calculated with no filter and the angular velocity states are calculated with filters.
-'''RADAlqi_est''' : This macro will cause the system to use an LQI controller on the whole system. A traditional estimator is used to estimate the states.
-'''rada_lqg''' : This macro will cause the entire system to be controlled by a LQG controller/estimator system.
-'''rada_split_lqg''' : This macro will cause the pendulum and ground robot to be controlled by their own LQG systems.
-'''rada_split_lqg_ol''' : This macro will cause the pendulum to be controlled by an LQG controller, the yaw of the ground robot to be controlled by a PID controller, and the ground robot linear velocities to be controlled with open-loop commands.
-'''yaw_off''' : This macro will cause the yaw control to be disabled on some controllers.
*'''accR''' : This macro will cause the PID linear velocity controllers to be given ramps to acclerate from one velocity to another instead of steps.
-'''posRamp''' : This macro will cause the linear velocities of RADA to be controlled by position PIDs with ramp reference instead of velocity commands.
-If no controller selection is made all controllers revert to PID controllers
All of these macros can be defined simply by uncommenting the corresponding define statement in main.cpp. The macros in the logger.cpp can be seen below:
-'''ssDrop''' : This macro puts the logger into packed drop controller mode and logs the correct values for the packet drop controllers.
-'''RADAlqi''' : This macro puts the logger into full system LQI controller logging mode.
-'''RADAlqi_est''' : This macro puts the logger into full system LQI controller plus estimator logging mode.
-'''rada_lqg''' : This puts the logger into full system LQG controller logging mode.
-'''rada_split_lqg''' : This macro causes the logger to log data about the subsystem LQG controllers.
-'''rada_split_lqg_ol''' : This cause the system to log data about the pendulum LQG system and the open-loop linear velocity commands.
-'''H2ctrl''' : This macro causes the logger to log data about the full system H2 controllers.
-If no logging mode is selected then the logger will default to logging PID data.
Because the system only calculates controllers for one set of controllers it is important to ensure that the logger is in the correct mode based off of what is defined in main.cpp. As of August 1st, 2016 the defines in main.cpp are not seen in logger.cpp.
Finally in a command prompt navigate to the driectroy: ''~/Desktop/rada_research_project/ErisResearchCode/CppProjects/MainProgram_PacketLoss''
Here just type: ''make''. The code will compile for your desired mode. For setting up a new development directory see [http://wikis.ece.iastate.edu/robotic-agriculture-data-acquisition/index.php/Setting_up_a_new_development_environment Setting up a new development environment] from the RADA senior Design wiki.
[[Image:ComplingRADACode.png|800px]]
The complied executable code ends up in ''/home/shared/MainProject''. The ''/home/shared'' directory is setup as a network file share (NFS).
[[Image:ErisCompliedCode-config.png|800px]]
This service needs to be restarted when CO3050-11 is restarted. [http://wikis.ece.iastate.edu/robotic-agriculture-data-acquisition/index.php/Configuring_NFS_shares_for_the_robot Configure NFS shares for the robot] from the RADA Senior Design wiki. Be sure to use the new Linux install command in step six. Though I have fond that even on a good strt the ''[ok]'' messages will still print.
=== Turing on RADA ===
Turing on Eris is fairly simple. Each system has its own battery. There is one for the wheels that plugs in at the front of Eris (opposite side of the swiches), one for the electronics in the back of Eris (in between the switches), and one for the propellers that goes on top of Eris.
[[Image:ErisOnPhoto.jpg|800px]]
The wheel battery is normally 1600 mAh 2-cell Lipo but any 2-cell Lipo will work. The wheels are turned on by flipping the silver switch so the top points away from the system. The electronics normally use a 2600 mAh 2-cell Lipo. The electronics are turned on by flipping the green switch away from the system. It is important that you only the WIFI adapter or Ethernet plugged in at the same time or VRPN my listen to the camera data broadcast over both connects which could cause problems. The propeller system is powered via a 2600 mAh 4-cell Lipo that connects to a power cable at the base of the pendulum. There is a switch to turn on the power to the propellers system. You will know it is on when the 1 on the switch is flush with the switch housing instead of sticking out. It takes about 30 seconds to a minute for Eris to boot up and start the networking connections. When the WIFI is plugged in you will know it is ready when a blue light turns on, on the module.
=== Connecting to RADA ===
RADA is controlled through an SSH connection. in a commands prompt, not the one you compile the code from so that you can recompile for different setup with out needing to close the connection. If you are using a WIFI connect use the command ''ssh root@192.168.0.53''. If you are connected to Eris through a LAN connaction use the command ''ssh root@192.168.0.54''. If the connection goes though you should be proped for a password.
The password is ''rootme''.
[[Image:Ssh2Eris.png|800px]]
It is important to close the SSH connection before turning off Eris because the terminal you are using will hang up if you don't. You can close the connection by using the command ''exit''.
[[Image:ClosingSSH.png|800px]]
== Testing RADA ==
Now that you are connected to Eris you can run tests. The testing is started by a few different methods.
=== Running the first test after power up ===
For the firs test after powering on Eris a few additional steps need to be completed in order to test the system. The FPGA motor controller needs to be programmed and Eris needs to connect the the NFS server running on CO3050-11. This is accomplished by running ''1_co3050-11.sh'', this shell scrip will setup the NFS, load the bit file into the FPGA configuration memory. Then it retrieves the executable file from the NFS server ''/mnt/nfs/MainProject and runs the executable. Once the user exits the executable the log file produces is copied from the ''~/Logs/YYYY_MM_DD_Day'' directory on Eris to ''/home/shared/MainProject/Logs/YYYY_MM_DD_Day'' on CO3050-11. When the folder for the current Eris date doesn't exist it creates this directory in CO3050-11 and then removes the directory and log file from Eris. You may see an warning that when coping the log file Eris couldn't maintain the file permisiion settings. This is normal as Eris doesn't have the same access to the NSF server as it has to its own files. This Date stamp uses date on Eris which is currently in June of 2008 as of August 2nd, 2016.
Before starting the test it is best to have someone spotting the pendulum a holding it near vertical so that the pendulum doesn't have issues when entering a control mode.'''<span style="color:red"> Always run ensure the pendulum is spotted by a second person when testing so you don't hurt yourself, others in the lab, or the RADA system.</span>''' Once you spotter is ready run the shell scrip by= using the command ''./1_co3050-11.sh'' in the terminal with the open SSH connection to Eris from the home, ''/root'', directory of Eris. When you run this script there will be a bunch of information printed out about the PIC bus and loading the bit file to configure the FPGA, you will know that RADA is ready for the test when it asks you to select a running mode. See the Testing Modes section below. This script can take a while to complete so beyond the first test after start up you don't need to run this script. See the Section about Running additional tests below.
[[Image:StartingRADA initial.png|800px]]
=== Testing Modes ===
The RADA system has three testing modes: Robot Control Mode, Tuning Mode, and Box Step Mode. Additionally you can exit the execution at any time by pressing the ''Esc'' key. Once the terminal asks you to chose a mode you can use the following commands to enter the desired mode with a three second delay or exit the program. You can also use these commands to switch between the modes.
-''v'' : Enters the pendulum PID tuning mode, this will only really work when using PIDs to control the pendulum.
-''b'' : Enter Robot control mode, in this mode you can drive the robot around and the pendulum will try to stay vertical. This is the main mode used for testing the whole RADA system.
-''n'' : Enters box step mode, where the pendulum will change its desired pitch and roll angles every 20 seconds and move in a box shape.
-''Esc'' : By hitting the escape key the program will exit the program.
You will almost always want to run Robot Control Mode as the other modes are legacy modes from when we initially built and tested RADA and only works with the pendulum PID controllers. There are also a few utility commands that can be used in all modes.
-''2'' : Resets I composts of the Pitch/Roll PIDs and only the PIDs.
-''m'' : Adds a marker to the Log file incase odd things happen somewhere. This just increments a counter so if you use it look for changes in the marker value.
==== Robot Control Model ====
In Robot control mode you can control the motion of Eris. For PID control of Eris or 1D state feedback system the directional commands command Eris body velocity were for full system and Eris system state feedback controllers control the global velocity. All of these keys only need to be pressed not held down.
-''w'' : Moves Eris forward (+x) at some velocity depending on the controller.
-''s'' : Moves Eris in reverse (-x) at some velocity depending on the controller.
-''d'' : Moves Eris in right (+y) at some velocity depending on the controller.
-''a'' : Moves Eris in left (-y) at some velocity depending on the controller.
-''p'' : Stops the motion of Eris (Set all velocity set points to zero). I.e. if you hit ''w'' then hit ''s'' then Eris will be moving in reverse.
-''y'' : Moves Eris forward and to the right (+x/+y) simultaneously at some velocity depending on the controller.
-''t'' : Moves Eris forward and to the left (+x/-y) simultaneously at some velocity depending on the controller.
-''i'' : Moves Eris reverse and to the right (-x/+y) simultaneously at some velocity depending on the controller.
-''y'' : Moves Eris reverse and to the left (-x/-y) simultaneously at some velocity depending on the controller.
-''e'' : Rotate Eris clockwise (+yaw) at some angular rate. This only worked when RADA used the closed-loop FPGA control of the wheels. There is currently no controllers that use this command.
-''q'' : Rotate Eris counter-clockwise (-yaw) at some angular rate. This only worked when RADA used the closed-loop FPGA control of the wheels. There is currently no controllers that use this command.
-''<'' : Increment Eris' desired heading 45 degrees counter-clockwise (-yaw).
-''>'' : Increment Eris' desired heading 45 degrees clockwise (+yaw).
-''7'' : Increments the pitch set point (+pitch).
-''4'' : Decrements the pitch set point (-pitch).
-''8'' : Increments the roll set point (+roll).
-''5'' : Decrements the roll set point (-roll).
==== Tuning Mode ====
Tuning mode allows you to tune the PID controllers for both pitch and roll. The UI commands here are also available in Box Step Mode.
-''1'' : Tune the Pitch PID.
-''3'' : Tune the Roll PID.
-''7'' : Increase proportional gain of PID being tuned.
-''4'' : Decrease proportional gain of PID being tuned.
-''8'' : Increase integral gain of PID being tuned.
-''5'' : Decrease integral gain of PID being tuned.
-''9'' : Increase derivative gain of PID being tuned.
-''6'' : Decrease derivative gain of PID being tuned.
-''i'' : Increase set point of PID being tuned.
-''k'' : Decrease set point of PID being tuned.
-''o'' : Increase integral windup term of PID being tuned. (Not used)
-''l'' : Decrease integral windup term of PID being tuned. (Not used)
==== Box Step Mode ====
Box set mode will automatically change the set points of the pendulum every 20 seconds. The case statement for this mode can be changed for 1D and 2D step modes. This mode allows the user to use he same commands as Tuning Mode.
=== Running additional Tests ===
Once you have run one test with Eris on it is unnecessary to configure the FPGA or connect to the NFS server again. This is what took much of the time in the initial setup. This is what the script ''3_stat_eris.sh'' was developed for. It does everything that ''1_co3050-11.sh'' does but without reprogramming the FPGA or reconnecting to the NFS server. As a result it is ready to test much quicker.
Before starting the test it is best to have someone spotting the pendulum a holding it near vertical so that the pendulum doesn't have issues when entering a control mode.'''<span style="color:red"> Always run ensure the pendulum is spotted by a second person when testing so you don't hurt yourself, others in the lab, or the RADA system.</span>''' Once you spotter is ready run the shell scrip by= using the command ''./3_start_eris.sh'' in the terminal with the open SSH connection to Eris from the home, ''/root'', directory of Eris.
[[Image:StartingRADA2nd.png|800px]]
=== Locating and retrieving log files ===
If you are only demoing the system there is no need to go beyond this point. Once you are done with a test that you want to compare to the model you should retrieve the log file right away so you don't mix it up with other test. On CO3050-11 go to the dircetory ''/home/shared/MainProject/Logs'' using the file browser (you can do this in a terminal but it is easier from the file explorer). Once there, look for the folder that has been modified most recently as Eris date is normally out of sync with its date and time. Then look for the newest log file. Log files are named like ''log(hh.mm.ss).txt'' (ex. log(13.04.51).txt). This naming convention works well to ensure that no log file is over written but it isn't useful of describing what the test was of or for. Copy this log to the Desktop or to a USB drive and rename it. A good method is to name the file something like ''RADA_ctrl_otherNote#.txt'', where Describes what system you tested (ex. RADA, RADA1D, PEN1D, PEN2D), what typ of controller was used, other notes and then a number if this is a repeat of another test. This is much more useful when looking back at these logs later on. Before transferring the log file for processing you should record the wheel and propeller battery voltages in the header of the log file. The log file format is both human readable and can be parsed by MATALB. It was designed by the first RADA Senior Design Team and more information about the log files can be found [http://wikis.ece.iastate.edu/robotic-agriculture-data-acquisition/index.php/Data_Analysis_Tool here.] See he section below on measuring battery voltage below in order to get the best measurements for simulation of RADA.
=== Measuring battery voltages ===
The last thing that you need to do before simulating an experiment of the RADA platform is record the battery voltages for both the wheels and propellers. The wheel battery can be measured unloaded as there isn't large line losses between the battery and the H-bridges. The propeller battery voltage needs to be measured under load because the power cord running up the pendulum has significant line losses at the currents the propellers draw when in use. The battery voltages can be recorded in the log file for the test. Open the log file for the test you just completed (Use KWrite for Linux machines or Notepad++ for Windows machines). The first few lines of the log is the headder. It should look like this:
#Constants pitch_P pitch_I pitch_D
#PIDValues 48000 18000 21000
#Constants roll_P roll_I roll_D
#PIDValues 48000 18000 21000
#Battery Vquad Vwheels
#Voltage
Follow the procedure for measuring the voltage of each battery and then record the voltage under the corresponding battery. Then save the log file and close out of your text editor and the test will be ready for processing. Recoding the battery voltages in this way makes it much easier to find if you need the value latter. The final log file header should look like this once you are done
#Constants pitch_P pitch_I pitch_D
#PIDValues 48000 18000 21000
#Constants roll_P roll_I roll_D
#PIDValues 48000 18000 21000
#Battery Vquad Vwheels
#Voltage 14.44 8.257
==== Wheel Battery ====
1. After test disconnect wheel battery from the system.
2. Measure voltage of battery using multimeter.
[[Image:MeasureVwheel.jpg|800px]]
You can use the plug used for charging the 2-cell Lipos but make sure to connect the plug to the multimeter before connecting the battery and disconnect the battery before disconnecting the plug from the mulitmeter. It is generally the best practice to give the multimeter a few minutes to allow for the voltage measurement to stabilize as the battery measurement tends to be a little low right after the test. The multimeter will report data out to four decimal places it is best just to round to three decimal places for the wheel voltage.
==== Quad Battery ====
1. Setup code to run all four propellers at 50% throttle, uncomment the definition of ''mot50'' in main.cpp and compile the project.
2. Power off propellers by turning off the switch to the ESCs.
3. Connect multimeter to measure the voltage across one of the ESCs. This is done by using the power splitter cord.
-Connect one of the female XT60 connectors on the splitter to a male XT60 connector to banana connector cable.
-The banana connector connect to the hand held multimeter. The multimeter should be set to the 20VDC measurement setting.
-Next unplug one the ESCs' power connection.
-reconnect the ESC to power through the two remain connectors on the spliter cable.
4. Power on the propellers.
5. Run the system at 50% throttle and measure the steady-state voltage during the test. The battery will slow the voltage decay significantly, meaning it will keep the same measurement for a few seconds.
6. Stop the test and record the voltage in the log file. Make sure to disconnect the batter before removing the splitter cable.
{| class="wikitable" style="text-align:center"
|-
| [[Image:PowerSplitter.jpg|200px]]
| [[Image:QuadMultiCon.jpg |200px]]
| [[Image:QuadMultiSet.JPG |200px]]
| [[Image:QuadMeasESCcon.JPG|200px]]
|-
| Splitter cord.
| Connect splitter to multimeter.
| Settings for multimeter.
| Connecting ESC through splitter.
|}
The testing setup should look like the image below:
[[Image:QuadBattMeas.jpg|800px]]
== Post processing and Simulation ==
Simulating a test of RADA starts with processing and storing the data. Then all of the parameters of the model are loaded in the MATLAB Workspace. Finally the Simulink file used for the simulation is opened and the length of the simulation is set to match the length of the actual test. The simulation is run and the simulation output is stored. Finally the data should be plotted and compared.
=== Using the MATLAB data parsing tool ===
In depth discussion of how to use the log file parsing tool is described [http://wikis.ece.iastate.edu/robotic-agriculture-data-acquisition/index.php/Data_Analysis_Tool here.] I suggest using the version of the tool in the rada_resarch_project git repository Paul Uhing used for his Master's research. It con be found on CO3050-11 under the ucart account in the directory ''~/rada_research_project/DataAnalysiTool_omnicoor/Tool''. Simply open MATLAB and set the working directory to this file path. In the MATLAB Command Prompt run ''DataAnalysis''. A popup window should open up. Select the log file you want to process and wait for the tool to finish processing the file. Once this is complete there should be four structures in the MATLAB workspace.
-'''main''' : This contains all of the data extracted from the log file and the processing parameters used. main.expData contains two time structures: Time is used for the pendulum data and Eris_time is used for the ground vehicle data.
-'''X_ref''' : This contains the reference vector in m/s for x velocity that is feed into Simulink. This expedites the simulation setup process, this used to be done by hand.
-'''Y_ref''' : This contains the reference vector in m/s for y velocity that is feed into Simulink. This expedites the simulation setup process, this used to be done by hand.
-'''Yaw_ref''' : This contains the reference vector in radians for yaw that is feed into Simulink. This expedites the simulation setup process, this used to be done by hand. This one is new incase people start testing the system with heading changes but is not used in the current setup.
The first thing you should do is rename the main structure to the name you used for the log file. This is helpful for comparing multiple tests. Next you will want to crate two new variable ''Vquad_test'' an Vw_test''. In the MATLAB Command Prompt set the measured propeller voltage from the log file to ''Vquad_test'' and set the measured the wheel voltage to ''Vw_test'' as this will be used by the simulation. Finally if you did an open-loop test of the wheels create the variable ''Uol'' and set it to the open-loop wheel command used. Save all of these variables from the MATLAB workspace to a ''.mat'' file of the same name as log file you extracted the data from and save it in the same directory as your RADA Simulink files. As of August 2nd, 2016 this directory is ''~/rada_research_project/MATLAB/RADA.''
=== Setting up the MATLAB workspace for simulation ===
Change your MATLAB directory to this directory. Then run the simulation setup files. Currently you just need to run ''modelParams_smallWheels_RADA'' in the MATLAB Command Prompt. Next open the Simulink file with that contains the model of RADA controlled by the controller you tested.
-'''RADA_psiCtrl_v2_lqi_est.slx''' contains LQI, LQI+estimation, and LQG controller simulations.
-'''RADA_psiCtrl_v2.slx''' contains the PID controlled system.
-'''RADA_psiCtrl_v2_LQGsep.slx''' contains the subsystem LQG controlled system.
-'''RADA_psiCtrl_v2_LQGsep_ol.slx''' contains the simulation of the pendulum system controlled by an LQG and Eris controlled with open-loop commands.
Note all of the current (August 2nd, 2016) ''.slx'' files were created in MATLAB 2014b and will only work in MATLAB 2014B or newer. Then in the MATLAB Command Prompt type ''X_ref.time(end)'' exactly, don't add a semicolon, and hit enter. MATLAB will print the time of the last command in the X_ref structure. Set the en time of the simulation to this value and save your Simulink file.
=== Running simulations and storing results ===
Before running the simulation make sure that the simuation is using the ''ode23t'' differential equations solver. This system is a moderately stiff system of differential and the ''ode45'' solver doesn't do well with these types of systems. When using ''ode23t'' is should only take a few minutes to run a 100+ second simulation while doing the same test using ''ode45'' could take 8 hours. While this slow it is also bad for your hard drive as the simulation has to page between RAM and your computers hard drive a lot.
Once this check is done run the simulation. While it is running check what the output structures variables are named for for your RADA test system. Once the simulation is done go to your MATLAB Workspace and select all 15 outputs for your simulation or your sub-simulation if you used '''RADA_psiCtrl_v2_lqi_est.slx'''. Save these 15 output structures to a ''.mat'' file named as the log file with _sim appended to the end of the name.
The 15 outputs are structures containing a time vector and then the data from the simulation sampled at 100 Hz and the units of this data are the SI units (ex: radians, m/s). There is one output structure for x velocity, y velocity, x body velocity, y body velocity, theta (pitch), phi (roll), psi (yaw), and one per actuator command (ex: the command sent to a wheel). Now you have all the data you can plot it.
=== Plotting results ===
If you look at the ''DataSets'' folder below ''~/rada_research_project/MATLAB/RADA'' directory there are plenty of examples of how Paul Uhing compared simulation to test data. Generally you should grate a ''.m'' file with the same name as the log file this data was extracted from with _plot appended to the name.
Generally you can just copy an for RADA_LQG_compPID_plot.m RADA_PID_compLQG_plot.m, RADA_LQG_sep_plot.m, or RADA_LQG_sep_ol_plot.m files and rename the structures for your test.
These files create four figures. Figure 1 plots compares the x velocity data in the first sub figure and compares pitch (theta) data in the second sub figure. Figure 2 does the same thing as Figure 1 but with y velocity and roll data. Figure 3 looks at the yaw data. Finally, Figure 4 looks at the sample period between UAV and ERIS packets from the camera system just to check for periods of time with large packet drops.
You can follow a similar pattern to compare motor commands. Just make sure that you compare Quad Motor 2 from the test data with Quad Motor 4 from simulation and vise versa because propellers 2 and 4 were switch in Eris's software compared to the Model.
That is all you need to know for testing RADA against the model.
b4b450113afaf0f1b4355715a442e39c358d8d0e
330
329
2016-09-21T14:42:24Z
Jonessk
7
/* Building Software */
wikitext
text/x-wiki
This page will take you though setting up and testing RADA, retrieving the log file and other necessary data to run a simulation of that test and processing the data in MATLAB. Then actually running the simulation of RADA in Simulink. The initial setup and how to test the system can also be applied to demoing RADA.
== Setting Up a RADA Test ==
Testing RADA is not overly difficult once you get the hang of the steps to setup RADA. The following steps may seem like a long process to go from starting the testing process to having completed simulation and plotting of the test results but this whole test procedure (with the exception of battery charging) can be completed in about 15-20 minutes. These steps are meant to be as detailed as possible in order to help new users of RADA get up and running as quickly as possible.
'''<span style="color:red">NOTE: Always run RADA with at least 2 people!</span>''' The pendulum arm can crash into the ground if the network starts to drop packets and one person cannot give commands to RADA and spot the pendulum. This is a safety issue for both you and the RADA platform.
=== Charging Batteries ===
The lab currently uses mostly Hyperion batteries. We charge our batteries with a Hyperion EOS 1420i Net3 battery charger. For some general information about how to use this charger see [https://www.youtube.com/watch?v=-ox3EpzvsJ8 this video.]. In the lab we power this charger using the old Kepco Power supply because it is the only power supply that can supply enough current. Make sure that the power supply is set to an output voltage between 10.5V-29V.
{| class="wikitable" style="text-align:center"
|-
| [[Image:ChargerPowerSupplyOff.JPG|400px]]
| [[Image:ChargerPowerSuplyOn.JPG|400px]]
|-
| Kepco Power Supply off.
| Kepco Power Supply on with correct voltage supply range.
|}
The YouTube video link above should explain how to use the charger. RADA currently uses three different Lithium polymer (Lipo) batteries: 1600 mAh 2-cell Lipo for the wheels, 2600 mAh 2-cell Lipo for the electronics of Eris, and a 2600 mAh 4-cell Lipo for the propellers. The 1600 mAh 2-cell Lipo can be charged using memory slot 2 of the charger. The 2600 mAh 2-cell Lipos can be charged using memory slot 3 for fast charging and memory slot 4 for slower charging (use this if the battery voltage drops really low for 10-20 minutes then switch to fast charging). The 2600 mAh 4-cell Lipo can be charged using memory slot 8. The 1600 mAh 2-cell and 2600 mAh 4-cell generally charge in 10-20 minutes apiece while the 2600 mAh 2-cell generally take up to 70 minutes to charge fully.
=== Setting up the Camera System ===
The camera system is run on the windows computer CO3050-07. You can log into this computer using a local microcart username and password (not posted here for security reasons, but any one who works in the lab should know it). Once logged in, look for Tracking Tools in the start menu or look for the shortcut shown below:
[[Image:TrackingTools_shortcut.PNG|thumb|center|Tracking Tools shortcut]]
Once the program opens the screen should look something like this:
[[Image:NewTrackingTools.PNG|800px]]
In the Tracking Tools Quick Start pop up menu select Open Existing Project and then navigate to ''D:\Optitrack_Configuration'' (It should open to this directory by default) and select the most recent Tracking Tools project. It should have the naming scheme ''TrackingToolsProject YYYY-MM-DD timeStamp.ttp''. This is normally the most recently edited file when sorting by date modified. The most recent one as of August 1st, 2016 is ''TrackingToolsProject 2015-09-23 2.30pm.ttp''.
[[Image:OpeningProject.PNG|800px]]
You should notice that the cameras shown in the main project screen arrange themselves like the camera system configuration once the project has been opened. Now the constellations need to be loaded. This can be done by going to ''File->Open'' and another popup window will open. Navigate back to ''D:\Optitrack_Configuration'' (It should open to this directory by default) and select the most recently dated set of RADA trackables. They have the naming scheme ''RADA_entireSystem_M_D_YYYY.tra''. The most recent one as of August 1st, 2016 is ''RADA_entireSystem_7_8_2016.tra''.
[[Image:Opening_trackables.PNG|800px]]
Once the project and trackables are open, the cameras should appear in their constellation (square) and there should be two constellations under ''Project Explorer->Trackables''. One named UAV for the pendulum and one named ERIS for the ground vehicle. In order to get additional information about each constellation, left click on the the name of the desired trackable.
[[Image:SelectingUAV.PNG|800px]]
Once a trackable is selected more information about it is available in the ''Trackables'' Tab on the right side of the screen. For the current position and orientation look at the ''Real-Time Info'' sub-tab. This gives the orientation in the wrong order for how we currently use the Euler angles. When two or three of the angles are near zero you can switch yaw and pitch to get roughly the correct orientation.
[[Image:Uav_realTimeInfo.PNG|800px]]
Now we need check to make sure the system is zeroed.
1. Hold RADA so that the front of the ground robot (ERIS is facing the wall with the white boards (east)). The front side of Eris is labeled. If it isn't, the front is the side opposite the switches and the side with the trackable constellation on it.
2. Make sure that the motor with the red motor mount is also facing the wall with the white boards.
3. Make sure the quad system is aligned along Eris Axis by standing behind the system. If the system is aligned, you should be able to block the mounting bolts of the front propeller motor with the pole while facing the east wall.
4. While holding the pendulum approximately vertical, see if the camera system reads zeros for the pendulum (UAV) pitch and roll (yaw and roll in ''Real-Time Info''). If yaw is off by a few degrees that is fine.
5. Compare the yaw of the UAV to that of ERIS (Remember this is pitch in ''Real-Time Info''). If they are both near zero and within a few degrees and the pendulum's pitch/roll were also near zero then you are ready to use the camera system. Otherwise, go to the next step.
6. You need to zero the pendulum.
- Align ERIS so it is near zero yaw first (eye ball it).
- Get a level and a friend. Have your friend use a level to ensure that the pendulum is level in both directions and hold it there.
- With the UAV constellation selected go to the ''Orientation'' tab (next to ''Real-Time Info'' tab) and click on ''Reset To Current Orientation button''
- Now your friend can set the pendulum down and you can zero ERIS the same way.
7. Save the new trackable orientation by going to ''File->Save Trackables...'' and save a file using the same naming conventions as the trackable file you opened earlier. Use the current data so you don't have to re-zero the system the next time you test.
[[Image:Uav_ResetOrientation.PNG|800px]]
=== Building Software ===
The development environment for running RADA is hosted on CO3050-11, a Linux Red Hat environment. This computer has a local ucart user name that you should use (the password isn't put here for security reasons). First, ensure that the RADA software is setup correctly for the test you want to run. To do this, you will need to open the main.cpp and logger.cpp files and make sure all of the compile time macros you want are defined correctly. All of the c++ files you should need to edit are in the directory ''~/Desktop/rada_research_project/ErisResearchCode/CppProjects/MainProgram_PacketLoss/src/Korebot'' Below are compiler macro options for main.cpp:
-'''H2ctrl''' : This will cause the system to enter H2 controller mode where the whole RADA system is controlled by an H2 controller.
-'''ssTracking''' : H2ctrl must also be defined for this macro to do anything. This macro will has the system to be controlled by a tracking H2 controller.
-'''ssMotors''' : H2ctrl must also be defined for this macro to do anything. This macro will has the system to be controlled by an H2 contorller that contains propeller states. This also causes the system to "Dance."
-'''ssDrop''' : Cause the system to go into packet drop controller mode. This mode allows controllers designed for lossy networks to be tested. Based off of other definitions how lossy the network is can be simulated. If nothing else is defined this controller becomes basically a H2 controller.
-'''drop10''' : Will put the packet drop mode into 10% loss mode and use a controller designed for 10% loss.
-'''drop30''' : Will put the packet drop mode into 30% loss mode and use a controller designed for 30% loss.
-'''drop50''' : Will put the packet drop mode into 50% loss mode and use a controller designed for 50% loss.
-'''mot50''' : This macro over-rides all other macros. If this is turned on the wheels will not run and the propellers will be run at 50% command. This is used for measuring the effective battery voltage seen by the ESCs. This is always run after a test.
-'''RADAlqi''' : This macro will cause the system to use an LQI controller on the whole system. The linear velocity states are calculated with no filter and the angular velocity states are calculated with filters.
-'''RADAlqi_est''' : This macro will cause the system to use an LQI controller on the whole system. A traditional estimator is used to estimate the states.
-'''rada_lqg''' : This macro will cause the entire system to be controlled by an LQG controller/estimator system.
-'''rada_split_lqg''' : This macro will cause the pendulum and ground robot to be controlled by their own LQG systems.
-'''rada_split_lqg_ol''' : This macro will cause the pendulum to be controlled by an LQG controller, the yaw of the ground robot to be controlled by a PID controller, and the ground robot linear velocities to be controlled with open-loop commands.
-'''yaw_off''' : This macro will cause the yaw control to be disabled on some controllers.
*'''accR''' : This macro will cause the PID linear velocity controllers to be given ramps to accelerate from one velocity to another instead of steps.
-'''posRamp''' : This macro will cause the linear velocities of RADA to be controlled by position PIDs with ramp reference instead of velocity commands.
-If no controller selection is made all controllers revert to PID controllers
All of these macros can be defined simply by uncommenting the corresponding define statement in main.cpp. The macros in the logger.cpp can be seen below:
-'''ssDrop''' : This macro puts the logger into packet drop controller mode and logs the correct values for the packet drop controllers.
-'''RADAlqi''' : This macro puts the logger into full system LQI controller logging mode.
-'''RADAlqi_est''' : This macro puts the logger into full system LQI controller plus estimator logging mode.
-'''rada_lqg''' : This puts the logger into full system LQG controller logging mode.
-'''rada_split_lqg''' : This macro causes the logger to log data about the subsystem LQG controllers.
-'''rada_split_lqg_ol''' : This cause the system to log data about the pendulum LQG system and the open-loop linear velocity commands.
-'''H2ctrl''' : This macro causes the logger to log data about the full system H2 controllers.
-If no logging mode is selected then the logger will default to logging PID data.
Because the system only calculates controllers for one set of controllers it is important to ensure that the logger is in the correct mode based off of what is defined in main.cpp. As of August 1st, 2016 the defines in main.cpp are not seen in logger.cpp.
Finally in a command prompt navigate to the driectroy: ''~/Desktop/rada_research_project/ErisResearchCode/CppProjects/MainProgram_PacketLoss''
Here just type: ''make''. The code will compile for your desired mode. For setting up a new development directory see [http://wikis.ece.iastate.edu/robotic-agriculture-data-acquisition/index.php/Setting_up_a_new_development_environment Setting up a new development environment] from the RADA Senior Design wiki.
[[Image:ComplingRADACode.png|800px]]
The complied executable code ends up in ''/home/shared/MainProject''. The ''/home/shared'' directory is setup as a network file share (NFS).
[[Image:ErisCompliedCode-config.png|800px]]
This service needs to be restarted when CO3050-11 is restarted. [http://wikis.ece.iastate.edu/robotic-agriculture-data-acquisition/index.php/Configuring_NFS_shares_for_the_robot Configure NFS shares for the robot] from the RADA Senior Design wiki. Be sure to use the new Linux install command in step six. Though I have found that even on a good strt the ''[ok]'' messages will still print.
=== Turing on RADA ===
Turing on Eris is fairly simple. Each system has its own battery. There is one for the wheels that plugs in at the front of Eris (opposite side of the swiches), one for the electronics in the back of Eris (in between the switches), and one for the propellers that goes on top of Eris.
[[Image:ErisOnPhoto.jpg|800px]]
The wheel battery is normally 1600 mAh 2-cell Lipo but any 2-cell Lipo will work. The wheels are turned on by flipping the silver switch so the top points away from the system. The electronics normally use a 2600 mAh 2-cell Lipo. The electronics are turned on by flipping the green switch away from the system. It is important that you only the WIFI adapter or Ethernet plugged in at the same time or VRPN my listen to the camera data broadcast over both connects which could cause problems. The propeller system is powered via a 2600 mAh 4-cell Lipo that connects to a power cable at the base of the pendulum. There is a switch to turn on the power to the propellers system. You will know it is on when the 1 on the switch is flush with the switch housing instead of sticking out. It takes about 30 seconds to a minute for Eris to boot up and start the networking connections. When the WIFI is plugged in you will know it is ready when a blue light turns on, on the module.
=== Connecting to RADA ===
RADA is controlled through an SSH connection. in a commands prompt, not the one you compile the code from so that you can recompile for different setup with out needing to close the connection. If you are using a WIFI connect use the command ''ssh root@192.168.0.53''. If you are connected to Eris through a LAN connaction use the command ''ssh root@192.168.0.54''. If the connection goes though you should be proped for a password.
The password is ''rootme''.
[[Image:Ssh2Eris.png|800px]]
It is important to close the SSH connection before turning off Eris because the terminal you are using will hang up if you don't. You can close the connection by using the command ''exit''.
[[Image:ClosingSSH.png|800px]]
== Testing RADA ==
Now that you are connected to Eris you can run tests. The testing is started by a few different methods.
=== Running the first test after power up ===
For the firs test after powering on Eris a few additional steps need to be completed in order to test the system. The FPGA motor controller needs to be programmed and Eris needs to connect the the NFS server running on CO3050-11. This is accomplished by running ''1_co3050-11.sh'', this shell scrip will setup the NFS, load the bit file into the FPGA configuration memory. Then it retrieves the executable file from the NFS server ''/mnt/nfs/MainProject and runs the executable. Once the user exits the executable the log file produces is copied from the ''~/Logs/YYYY_MM_DD_Day'' directory on Eris to ''/home/shared/MainProject/Logs/YYYY_MM_DD_Day'' on CO3050-11. When the folder for the current Eris date doesn't exist it creates this directory in CO3050-11 and then removes the directory and log file from Eris. You may see an warning that when coping the log file Eris couldn't maintain the file permisiion settings. This is normal as Eris doesn't have the same access to the NSF server as it has to its own files. This Date stamp uses date on Eris which is currently in June of 2008 as of August 2nd, 2016.
Before starting the test it is best to have someone spotting the pendulum a holding it near vertical so that the pendulum doesn't have issues when entering a control mode.'''<span style="color:red"> Always run ensure the pendulum is spotted by a second person when testing so you don't hurt yourself, others in the lab, or the RADA system.</span>''' Once you spotter is ready run the shell scrip by= using the command ''./1_co3050-11.sh'' in the terminal with the open SSH connection to Eris from the home, ''/root'', directory of Eris. When you run this script there will be a bunch of information printed out about the PIC bus and loading the bit file to configure the FPGA, you will know that RADA is ready for the test when it asks you to select a running mode. See the Testing Modes section below. This script can take a while to complete so beyond the first test after start up you don't need to run this script. See the Section about Running additional tests below.
[[Image:StartingRADA initial.png|800px]]
=== Testing Modes ===
The RADA system has three testing modes: Robot Control Mode, Tuning Mode, and Box Step Mode. Additionally you can exit the execution at any time by pressing the ''Esc'' key. Once the terminal asks you to chose a mode you can use the following commands to enter the desired mode with a three second delay or exit the program. You can also use these commands to switch between the modes.
-''v'' : Enters the pendulum PID tuning mode, this will only really work when using PIDs to control the pendulum.
-''b'' : Enter Robot control mode, in this mode you can drive the robot around and the pendulum will try to stay vertical. This is the main mode used for testing the whole RADA system.
-''n'' : Enters box step mode, where the pendulum will change its desired pitch and roll angles every 20 seconds and move in a box shape.
-''Esc'' : By hitting the escape key the program will exit the program.
You will almost always want to run Robot Control Mode as the other modes are legacy modes from when we initially built and tested RADA and only works with the pendulum PID controllers. There are also a few utility commands that can be used in all modes.
-''2'' : Resets I composts of the Pitch/Roll PIDs and only the PIDs.
-''m'' : Adds a marker to the Log file incase odd things happen somewhere. This just increments a counter so if you use it look for changes in the marker value.
==== Robot Control Model ====
In Robot control mode you can control the motion of Eris. For PID control of Eris or 1D state feedback system the directional commands command Eris body velocity were for full system and Eris system state feedback controllers control the global velocity. All of these keys only need to be pressed not held down.
-''w'' : Moves Eris forward (+x) at some velocity depending on the controller.
-''s'' : Moves Eris in reverse (-x) at some velocity depending on the controller.
-''d'' : Moves Eris in right (+y) at some velocity depending on the controller.
-''a'' : Moves Eris in left (-y) at some velocity depending on the controller.
-''p'' : Stops the motion of Eris (Set all velocity set points to zero). I.e. if you hit ''w'' then hit ''s'' then Eris will be moving in reverse.
-''y'' : Moves Eris forward and to the right (+x/+y) simultaneously at some velocity depending on the controller.
-''t'' : Moves Eris forward and to the left (+x/-y) simultaneously at some velocity depending on the controller.
-''i'' : Moves Eris reverse and to the right (-x/+y) simultaneously at some velocity depending on the controller.
-''y'' : Moves Eris reverse and to the left (-x/-y) simultaneously at some velocity depending on the controller.
-''e'' : Rotate Eris clockwise (+yaw) at some angular rate. This only worked when RADA used the closed-loop FPGA control of the wheels. There is currently no controllers that use this command.
-''q'' : Rotate Eris counter-clockwise (-yaw) at some angular rate. This only worked when RADA used the closed-loop FPGA control of the wheels. There is currently no controllers that use this command.
-''<'' : Increment Eris' desired heading 45 degrees counter-clockwise (-yaw).
-''>'' : Increment Eris' desired heading 45 degrees clockwise (+yaw).
-''7'' : Increments the pitch set point (+pitch).
-''4'' : Decrements the pitch set point (-pitch).
-''8'' : Increments the roll set point (+roll).
-''5'' : Decrements the roll set point (-roll).
==== Tuning Mode ====
Tuning mode allows you to tune the PID controllers for both pitch and roll. The UI commands here are also available in Box Step Mode.
-''1'' : Tune the Pitch PID.
-''3'' : Tune the Roll PID.
-''7'' : Increase proportional gain of PID being tuned.
-''4'' : Decrease proportional gain of PID being tuned.
-''8'' : Increase integral gain of PID being tuned.
-''5'' : Decrease integral gain of PID being tuned.
-''9'' : Increase derivative gain of PID being tuned.
-''6'' : Decrease derivative gain of PID being tuned.
-''i'' : Increase set point of PID being tuned.
-''k'' : Decrease set point of PID being tuned.
-''o'' : Increase integral windup term of PID being tuned. (Not used)
-''l'' : Decrease integral windup term of PID being tuned. (Not used)
==== Box Step Mode ====
Box set mode will automatically change the set points of the pendulum every 20 seconds. The case statement for this mode can be changed for 1D and 2D step modes. This mode allows the user to use he same commands as Tuning Mode.
=== Running additional Tests ===
Once you have run one test with Eris on it is unnecessary to configure the FPGA or connect to the NFS server again. This is what took much of the time in the initial setup. This is what the script ''3_stat_eris.sh'' was developed for. It does everything that ''1_co3050-11.sh'' does but without reprogramming the FPGA or reconnecting to the NFS server. As a result it is ready to test much quicker.
Before starting the test it is best to have someone spotting the pendulum a holding it near vertical so that the pendulum doesn't have issues when entering a control mode.'''<span style="color:red"> Always run ensure the pendulum is spotted by a second person when testing so you don't hurt yourself, others in the lab, or the RADA system.</span>''' Once you spotter is ready run the shell scrip by= using the command ''./3_start_eris.sh'' in the terminal with the open SSH connection to Eris from the home, ''/root'', directory of Eris.
[[Image:StartingRADA2nd.png|800px]]
=== Locating and retrieving log files ===
If you are only demoing the system there is no need to go beyond this point. Once you are done with a test that you want to compare to the model you should retrieve the log file right away so you don't mix it up with other test. On CO3050-11 go to the dircetory ''/home/shared/MainProject/Logs'' using the file browser (you can do this in a terminal but it is easier from the file explorer). Once there, look for the folder that has been modified most recently as Eris date is normally out of sync with its date and time. Then look for the newest log file. Log files are named like ''log(hh.mm.ss).txt'' (ex. log(13.04.51).txt). This naming convention works well to ensure that no log file is over written but it isn't useful of describing what the test was of or for. Copy this log to the Desktop or to a USB drive and rename it. A good method is to name the file something like ''RADA_ctrl_otherNote#.txt'', where Describes what system you tested (ex. RADA, RADA1D, PEN1D, PEN2D), what typ of controller was used, other notes and then a number if this is a repeat of another test. This is much more useful when looking back at these logs later on. Before transferring the log file for processing you should record the wheel and propeller battery voltages in the header of the log file. The log file format is both human readable and can be parsed by MATALB. It was designed by the first RADA Senior Design Team and more information about the log files can be found [http://wikis.ece.iastate.edu/robotic-agriculture-data-acquisition/index.php/Data_Analysis_Tool here.] See he section below on measuring battery voltage below in order to get the best measurements for simulation of RADA.
=== Measuring battery voltages ===
The last thing that you need to do before simulating an experiment of the RADA platform is record the battery voltages for both the wheels and propellers. The wheel battery can be measured unloaded as there isn't large line losses between the battery and the H-bridges. The propeller battery voltage needs to be measured under load because the power cord running up the pendulum has significant line losses at the currents the propellers draw when in use. The battery voltages can be recorded in the log file for the test. Open the log file for the test you just completed (Use KWrite for Linux machines or Notepad++ for Windows machines). The first few lines of the log is the headder. It should look like this:
#Constants pitch_P pitch_I pitch_D
#PIDValues 48000 18000 21000
#Constants roll_P roll_I roll_D
#PIDValues 48000 18000 21000
#Battery Vquad Vwheels
#Voltage
Follow the procedure for measuring the voltage of each battery and then record the voltage under the corresponding battery. Then save the log file and close out of your text editor and the test will be ready for processing. Recoding the battery voltages in this way makes it much easier to find if you need the value latter. The final log file header should look like this once you are done
#Constants pitch_P pitch_I pitch_D
#PIDValues 48000 18000 21000
#Constants roll_P roll_I roll_D
#PIDValues 48000 18000 21000
#Battery Vquad Vwheels
#Voltage 14.44 8.257
==== Wheel Battery ====
1. After test disconnect wheel battery from the system.
2. Measure voltage of battery using multimeter.
[[Image:MeasureVwheel.jpg|800px]]
You can use the plug used for charging the 2-cell Lipos but make sure to connect the plug to the multimeter before connecting the battery and disconnect the battery before disconnecting the plug from the mulitmeter. It is generally the best practice to give the multimeter a few minutes to allow for the voltage measurement to stabilize as the battery measurement tends to be a little low right after the test. The multimeter will report data out to four decimal places it is best just to round to three decimal places for the wheel voltage.
==== Quad Battery ====
1. Setup code to run all four propellers at 50% throttle, uncomment the definition of ''mot50'' in main.cpp and compile the project.
2. Power off propellers by turning off the switch to the ESCs.
3. Connect multimeter to measure the voltage across one of the ESCs. This is done by using the power splitter cord.
-Connect one of the female XT60 connectors on the splitter to a male XT60 connector to banana connector cable.
-The banana connector connect to the hand held multimeter. The multimeter should be set to the 20VDC measurement setting.
-Next unplug one the ESCs' power connection.
-reconnect the ESC to power through the two remain connectors on the spliter cable.
4. Power on the propellers.
5. Run the system at 50% throttle and measure the steady-state voltage during the test. The battery will slow the voltage decay significantly, meaning it will keep the same measurement for a few seconds.
6. Stop the test and record the voltage in the log file. Make sure to disconnect the batter before removing the splitter cable.
{| class="wikitable" style="text-align:center"
|-
| [[Image:PowerSplitter.jpg|200px]]
| [[Image:QuadMultiCon.jpg |200px]]
| [[Image:QuadMultiSet.JPG |200px]]
| [[Image:QuadMeasESCcon.JPG|200px]]
|-
| Splitter cord.
| Connect splitter to multimeter.
| Settings for multimeter.
| Connecting ESC through splitter.
|}
The testing setup should look like the image below:
[[Image:QuadBattMeas.jpg|800px]]
== Post processing and Simulation ==
Simulating a test of RADA starts with processing and storing the data. Then all of the parameters of the model are loaded in the MATLAB Workspace. Finally the Simulink file used for the simulation is opened and the length of the simulation is set to match the length of the actual test. The simulation is run and the simulation output is stored. Finally the data should be plotted and compared.
=== Using the MATLAB data parsing tool ===
In depth discussion of how to use the log file parsing tool is described [http://wikis.ece.iastate.edu/robotic-agriculture-data-acquisition/index.php/Data_Analysis_Tool here.] I suggest using the version of the tool in the rada_resarch_project git repository Paul Uhing used for his Master's research. It con be found on CO3050-11 under the ucart account in the directory ''~/rada_research_project/DataAnalysiTool_omnicoor/Tool''. Simply open MATLAB and set the working directory to this file path. In the MATLAB Command Prompt run ''DataAnalysis''. A popup window should open up. Select the log file you want to process and wait for the tool to finish processing the file. Once this is complete there should be four structures in the MATLAB workspace.
-'''main''' : This contains all of the data extracted from the log file and the processing parameters used. main.expData contains two time structures: Time is used for the pendulum data and Eris_time is used for the ground vehicle data.
-'''X_ref''' : This contains the reference vector in m/s for x velocity that is feed into Simulink. This expedites the simulation setup process, this used to be done by hand.
-'''Y_ref''' : This contains the reference vector in m/s for y velocity that is feed into Simulink. This expedites the simulation setup process, this used to be done by hand.
-'''Yaw_ref''' : This contains the reference vector in radians for yaw that is feed into Simulink. This expedites the simulation setup process, this used to be done by hand. This one is new incase people start testing the system with heading changes but is not used in the current setup.
The first thing you should do is rename the main structure to the name you used for the log file. This is helpful for comparing multiple tests. Next you will want to crate two new variable ''Vquad_test'' an Vw_test''. In the MATLAB Command Prompt set the measured propeller voltage from the log file to ''Vquad_test'' and set the measured the wheel voltage to ''Vw_test'' as this will be used by the simulation. Finally if you did an open-loop test of the wheels create the variable ''Uol'' and set it to the open-loop wheel command used. Save all of these variables from the MATLAB workspace to a ''.mat'' file of the same name as log file you extracted the data from and save it in the same directory as your RADA Simulink files. As of August 2nd, 2016 this directory is ''~/rada_research_project/MATLAB/RADA.''
=== Setting up the MATLAB workspace for simulation ===
Change your MATLAB directory to this directory. Then run the simulation setup files. Currently you just need to run ''modelParams_smallWheels_RADA'' in the MATLAB Command Prompt. Next open the Simulink file with that contains the model of RADA controlled by the controller you tested.
-'''RADA_psiCtrl_v2_lqi_est.slx''' contains LQI, LQI+estimation, and LQG controller simulations.
-'''RADA_psiCtrl_v2.slx''' contains the PID controlled system.
-'''RADA_psiCtrl_v2_LQGsep.slx''' contains the subsystem LQG controlled system.
-'''RADA_psiCtrl_v2_LQGsep_ol.slx''' contains the simulation of the pendulum system controlled by an LQG and Eris controlled with open-loop commands.
Note all of the current (August 2nd, 2016) ''.slx'' files were created in MATLAB 2014b and will only work in MATLAB 2014B or newer. Then in the MATLAB Command Prompt type ''X_ref.time(end)'' exactly, don't add a semicolon, and hit enter. MATLAB will print the time of the last command in the X_ref structure. Set the en time of the simulation to this value and save your Simulink file.
=== Running simulations and storing results ===
Before running the simulation make sure that the simuation is using the ''ode23t'' differential equations solver. This system is a moderately stiff system of differential and the ''ode45'' solver doesn't do well with these types of systems. When using ''ode23t'' is should only take a few minutes to run a 100+ second simulation while doing the same test using ''ode45'' could take 8 hours. While this slow it is also bad for your hard drive as the simulation has to page between RAM and your computers hard drive a lot.
Once this check is done run the simulation. While it is running check what the output structures variables are named for for your RADA test system. Once the simulation is done go to your MATLAB Workspace and select all 15 outputs for your simulation or your sub-simulation if you used '''RADA_psiCtrl_v2_lqi_est.slx'''. Save these 15 output structures to a ''.mat'' file named as the log file with _sim appended to the end of the name.
The 15 outputs are structures containing a time vector and then the data from the simulation sampled at 100 Hz and the units of this data are the SI units (ex: radians, m/s). There is one output structure for x velocity, y velocity, x body velocity, y body velocity, theta (pitch), phi (roll), psi (yaw), and one per actuator command (ex: the command sent to a wheel). Now you have all the data you can plot it.
=== Plotting results ===
If you look at the ''DataSets'' folder below ''~/rada_research_project/MATLAB/RADA'' directory there are plenty of examples of how Paul Uhing compared simulation to test data. Generally you should grate a ''.m'' file with the same name as the log file this data was extracted from with _plot appended to the name.
Generally you can just copy an for RADA_LQG_compPID_plot.m RADA_PID_compLQG_plot.m, RADA_LQG_sep_plot.m, or RADA_LQG_sep_ol_plot.m files and rename the structures for your test.
These files create four figures. Figure 1 plots compares the x velocity data in the first sub figure and compares pitch (theta) data in the second sub figure. Figure 2 does the same thing as Figure 1 but with y velocity and roll data. Figure 3 looks at the yaw data. Finally, Figure 4 looks at the sample period between UAV and ERIS packets from the camera system just to check for periods of time with large packet drops.
You can follow a similar pattern to compare motor commands. Just make sure that you compare Quad Motor 2 from the test data with Quad Motor 4 from simulation and vise versa because propellers 2 and 4 were switch in Eris's software compared to the Model.
That is all you need to know for testing RADA against the model.
71d6fbd4c2333d42e36c53dcf5823355ae81d831
331
330
2016-09-21T14:46:23Z
Jonessk
7
/* Turing on RADA */
wikitext
text/x-wiki
This page will take you though setting up and testing RADA, retrieving the log file and other necessary data to run a simulation of that test and processing the data in MATLAB. Then actually running the simulation of RADA in Simulink. The initial setup and how to test the system can also be applied to demoing RADA.
== Setting Up a RADA Test ==
Testing RADA is not overly difficult once you get the hang of the steps to setup RADA. The following steps may seem like a long process to go from starting the testing process to having completed simulation and plotting of the test results but this whole test procedure (with the exception of battery charging) can be completed in about 15-20 minutes. These steps are meant to be as detailed as possible in order to help new users of RADA get up and running as quickly as possible.
'''<span style="color:red">NOTE: Always run RADA with at least 2 people!</span>''' The pendulum arm can crash into the ground if the network starts to drop packets and one person cannot give commands to RADA and spot the pendulum. This is a safety issue for both you and the RADA platform.
=== Charging Batteries ===
The lab currently uses mostly Hyperion batteries. We charge our batteries with a Hyperion EOS 1420i Net3 battery charger. For some general information about how to use this charger see [https://www.youtube.com/watch?v=-ox3EpzvsJ8 this video.]. In the lab we power this charger using the old Kepco Power supply because it is the only power supply that can supply enough current. Make sure that the power supply is set to an output voltage between 10.5V-29V.
{| class="wikitable" style="text-align:center"
|-
| [[Image:ChargerPowerSupplyOff.JPG|400px]]
| [[Image:ChargerPowerSuplyOn.JPG|400px]]
|-
| Kepco Power Supply off.
| Kepco Power Supply on with correct voltage supply range.
|}
The YouTube video link above should explain how to use the charger. RADA currently uses three different Lithium polymer (Lipo) batteries: 1600 mAh 2-cell Lipo for the wheels, 2600 mAh 2-cell Lipo for the electronics of Eris, and a 2600 mAh 4-cell Lipo for the propellers. The 1600 mAh 2-cell Lipo can be charged using memory slot 2 of the charger. The 2600 mAh 2-cell Lipos can be charged using memory slot 3 for fast charging and memory slot 4 for slower charging (use this if the battery voltage drops really low for 10-20 minutes then switch to fast charging). The 2600 mAh 4-cell Lipo can be charged using memory slot 8. The 1600 mAh 2-cell and 2600 mAh 4-cell generally charge in 10-20 minutes apiece while the 2600 mAh 2-cell generally take up to 70 minutes to charge fully.
=== Setting up the Camera System ===
The camera system is run on the windows computer CO3050-07. You can log into this computer using a local microcart username and password (not posted here for security reasons, but any one who works in the lab should know it). Once logged in, look for Tracking Tools in the start menu or look for the shortcut shown below:
[[Image:TrackingTools_shortcut.PNG|thumb|center|Tracking Tools shortcut]]
Once the program opens the screen should look something like this:
[[Image:NewTrackingTools.PNG|800px]]
In the Tracking Tools Quick Start pop up menu select Open Existing Project and then navigate to ''D:\Optitrack_Configuration'' (It should open to this directory by default) and select the most recent Tracking Tools project. It should have the naming scheme ''TrackingToolsProject YYYY-MM-DD timeStamp.ttp''. This is normally the most recently edited file when sorting by date modified. The most recent one as of August 1st, 2016 is ''TrackingToolsProject 2015-09-23 2.30pm.ttp''.
[[Image:OpeningProject.PNG|800px]]
You should notice that the cameras shown in the main project screen arrange themselves like the camera system configuration once the project has been opened. Now the constellations need to be loaded. This can be done by going to ''File->Open'' and another popup window will open. Navigate back to ''D:\Optitrack_Configuration'' (It should open to this directory by default) and select the most recently dated set of RADA trackables. They have the naming scheme ''RADA_entireSystem_M_D_YYYY.tra''. The most recent one as of August 1st, 2016 is ''RADA_entireSystem_7_8_2016.tra''.
[[Image:Opening_trackables.PNG|800px]]
Once the project and trackables are open, the cameras should appear in their constellation (square) and there should be two constellations under ''Project Explorer->Trackables''. One named UAV for the pendulum and one named ERIS for the ground vehicle. In order to get additional information about each constellation, left click on the the name of the desired trackable.
[[Image:SelectingUAV.PNG|800px]]
Once a trackable is selected more information about it is available in the ''Trackables'' Tab on the right side of the screen. For the current position and orientation look at the ''Real-Time Info'' sub-tab. This gives the orientation in the wrong order for how we currently use the Euler angles. When two or three of the angles are near zero you can switch yaw and pitch to get roughly the correct orientation.
[[Image:Uav_realTimeInfo.PNG|800px]]
Now we need check to make sure the system is zeroed.
1. Hold RADA so that the front of the ground robot (ERIS is facing the wall with the white boards (east)). The front side of Eris is labeled. If it isn't, the front is the side opposite the switches and the side with the trackable constellation on it.
2. Make sure that the motor with the red motor mount is also facing the wall with the white boards.
3. Make sure the quad system is aligned along Eris Axis by standing behind the system. If the system is aligned, you should be able to block the mounting bolts of the front propeller motor with the pole while facing the east wall.
4. While holding the pendulum approximately vertical, see if the camera system reads zeros for the pendulum (UAV) pitch and roll (yaw and roll in ''Real-Time Info''). If yaw is off by a few degrees that is fine.
5. Compare the yaw of the UAV to that of ERIS (Remember this is pitch in ''Real-Time Info''). If they are both near zero and within a few degrees and the pendulum's pitch/roll were also near zero then you are ready to use the camera system. Otherwise, go to the next step.
6. You need to zero the pendulum.
- Align ERIS so it is near zero yaw first (eye ball it).
- Get a level and a friend. Have your friend use a level to ensure that the pendulum is level in both directions and hold it there.
- With the UAV constellation selected go to the ''Orientation'' tab (next to ''Real-Time Info'' tab) and click on ''Reset To Current Orientation button''
- Now your friend can set the pendulum down and you can zero ERIS the same way.
7. Save the new trackable orientation by going to ''File->Save Trackables...'' and save a file using the same naming conventions as the trackable file you opened earlier. Use the current data so you don't have to re-zero the system the next time you test.
[[Image:Uav_ResetOrientation.PNG|800px]]
=== Building Software ===
The development environment for running RADA is hosted on CO3050-11, a Linux Red Hat environment. This computer has a local ucart user name that you should use (the password isn't put here for security reasons). First, ensure that the RADA software is setup correctly for the test you want to run. To do this, you will need to open the main.cpp and logger.cpp files and make sure all of the compile time macros you want are defined correctly. All of the c++ files you should need to edit are in the directory ''~/Desktop/rada_research_project/ErisResearchCode/CppProjects/MainProgram_PacketLoss/src/Korebot'' Below are compiler macro options for main.cpp:
-'''H2ctrl''' : This will cause the system to enter H2 controller mode where the whole RADA system is controlled by an H2 controller.
-'''ssTracking''' : H2ctrl must also be defined for this macro to do anything. This macro will has the system to be controlled by a tracking H2 controller.
-'''ssMotors''' : H2ctrl must also be defined for this macro to do anything. This macro will has the system to be controlled by an H2 contorller that contains propeller states. This also causes the system to "Dance."
-'''ssDrop''' : Cause the system to go into packet drop controller mode. This mode allows controllers designed for lossy networks to be tested. Based off of other definitions how lossy the network is can be simulated. If nothing else is defined this controller becomes basically a H2 controller.
-'''drop10''' : Will put the packet drop mode into 10% loss mode and use a controller designed for 10% loss.
-'''drop30''' : Will put the packet drop mode into 30% loss mode and use a controller designed for 30% loss.
-'''drop50''' : Will put the packet drop mode into 50% loss mode and use a controller designed for 50% loss.
-'''mot50''' : This macro over-rides all other macros. If this is turned on the wheels will not run and the propellers will be run at 50% command. This is used for measuring the effective battery voltage seen by the ESCs. This is always run after a test.
-'''RADAlqi''' : This macro will cause the system to use an LQI controller on the whole system. The linear velocity states are calculated with no filter and the angular velocity states are calculated with filters.
-'''RADAlqi_est''' : This macro will cause the system to use an LQI controller on the whole system. A traditional estimator is used to estimate the states.
-'''rada_lqg''' : This macro will cause the entire system to be controlled by an LQG controller/estimator system.
-'''rada_split_lqg''' : This macro will cause the pendulum and ground robot to be controlled by their own LQG systems.
-'''rada_split_lqg_ol''' : This macro will cause the pendulum to be controlled by an LQG controller, the yaw of the ground robot to be controlled by a PID controller, and the ground robot linear velocities to be controlled with open-loop commands.
-'''yaw_off''' : This macro will cause the yaw control to be disabled on some controllers.
*'''accR''' : This macro will cause the PID linear velocity controllers to be given ramps to accelerate from one velocity to another instead of steps.
-'''posRamp''' : This macro will cause the linear velocities of RADA to be controlled by position PIDs with ramp reference instead of velocity commands.
-If no controller selection is made all controllers revert to PID controllers
All of these macros can be defined simply by uncommenting the corresponding define statement in main.cpp. The macros in the logger.cpp can be seen below:
-'''ssDrop''' : This macro puts the logger into packet drop controller mode and logs the correct values for the packet drop controllers.
-'''RADAlqi''' : This macro puts the logger into full system LQI controller logging mode.
-'''RADAlqi_est''' : This macro puts the logger into full system LQI controller plus estimator logging mode.
-'''rada_lqg''' : This puts the logger into full system LQG controller logging mode.
-'''rada_split_lqg''' : This macro causes the logger to log data about the subsystem LQG controllers.
-'''rada_split_lqg_ol''' : This cause the system to log data about the pendulum LQG system and the open-loop linear velocity commands.
-'''H2ctrl''' : This macro causes the logger to log data about the full system H2 controllers.
-If no logging mode is selected then the logger will default to logging PID data.
Because the system only calculates controllers for one set of controllers it is important to ensure that the logger is in the correct mode based off of what is defined in main.cpp. As of August 1st, 2016 the defines in main.cpp are not seen in logger.cpp.
Finally in a command prompt navigate to the driectroy: ''~/Desktop/rada_research_project/ErisResearchCode/CppProjects/MainProgram_PacketLoss''
Here just type: ''make''. The code will compile for your desired mode. For setting up a new development directory see [http://wikis.ece.iastate.edu/robotic-agriculture-data-acquisition/index.php/Setting_up_a_new_development_environment Setting up a new development environment] from the RADA Senior Design wiki.
[[Image:ComplingRADACode.png|800px]]
The complied executable code ends up in ''/home/shared/MainProject''. The ''/home/shared'' directory is setup as a network file share (NFS).
[[Image:ErisCompliedCode-config.png|800px]]
This service needs to be restarted when CO3050-11 is restarted. [http://wikis.ece.iastate.edu/robotic-agriculture-data-acquisition/index.php/Configuring_NFS_shares_for_the_robot Configure NFS shares for the robot] from the RADA Senior Design wiki. Be sure to use the new Linux install command in step six. Though I have found that even on a good strt the ''[ok]'' messages will still print.
=== Turning on RADA ===
Turning on Eris is fairly simple. Each system has its own battery. There is one for the wheels that plugs in at the front of Eris (opposite side of the switches), one for the electronics in the back of Eris (in between the switches), and one for the propellers that goes on top of Eris.
[[Image:ErisOnPhoto.jpg|800px]]
The wheel battery is normally 1600 mAh 2-cell Lipo but any 2-cell Lipo will work. The wheels are turned on by flipping the silver switch so the top points away from the system. The electronics normally use a 2600 mAh 2-cell Lipo. The electronics are turned on by flipping the green switch away from the system. It is important that you use EITHER the WIFI adapter OR hardwired Ethernet, because the VRPN may listen to the camera data broadcast over both connections which could cause problems. The propeller system is powered via a 2600 mAh 4-cell Lipo that connects to a power cable at the base of the pendulum. There is a switch to turn on the power to the propellers system. You will know it is on when the 1 on the switch is flush with the switch housing instead of sticking out. It takes about 30 seconds to a minute for Eris to boot up and start the networking connections. When the WIFI is plugged in, you will know it is ready when a blue light turns on, on the module.
=== Connecting to RADA ===
RADA is controlled through an SSH connection. in a commands prompt, not the one you compile the code from so that you can recompile for different setup with out needing to close the connection. If you are using a WIFI connect use the command ''ssh root@192.168.0.53''. If you are connected to Eris through a LAN connaction use the command ''ssh root@192.168.0.54''. If the connection goes though you should be proped for a password.
The password is ''rootme''.
[[Image:Ssh2Eris.png|800px]]
It is important to close the SSH connection before turning off Eris because the terminal you are using will hang up if you don't. You can close the connection by using the command ''exit''.
[[Image:ClosingSSH.png|800px]]
== Testing RADA ==
Now that you are connected to Eris you can run tests. The testing is started by a few different methods.
=== Running the first test after power up ===
For the firs test after powering on Eris a few additional steps need to be completed in order to test the system. The FPGA motor controller needs to be programmed and Eris needs to connect the the NFS server running on CO3050-11. This is accomplished by running ''1_co3050-11.sh'', this shell scrip will setup the NFS, load the bit file into the FPGA configuration memory. Then it retrieves the executable file from the NFS server ''/mnt/nfs/MainProject and runs the executable. Once the user exits the executable the log file produces is copied from the ''~/Logs/YYYY_MM_DD_Day'' directory on Eris to ''/home/shared/MainProject/Logs/YYYY_MM_DD_Day'' on CO3050-11. When the folder for the current Eris date doesn't exist it creates this directory in CO3050-11 and then removes the directory and log file from Eris. You may see an warning that when coping the log file Eris couldn't maintain the file permisiion settings. This is normal as Eris doesn't have the same access to the NSF server as it has to its own files. This Date stamp uses date on Eris which is currently in June of 2008 as of August 2nd, 2016.
Before starting the test it is best to have someone spotting the pendulum a holding it near vertical so that the pendulum doesn't have issues when entering a control mode.'''<span style="color:red"> Always run ensure the pendulum is spotted by a second person when testing so you don't hurt yourself, others in the lab, or the RADA system.</span>''' Once you spotter is ready run the shell scrip by= using the command ''./1_co3050-11.sh'' in the terminal with the open SSH connection to Eris from the home, ''/root'', directory of Eris. When you run this script there will be a bunch of information printed out about the PIC bus and loading the bit file to configure the FPGA, you will know that RADA is ready for the test when it asks you to select a running mode. See the Testing Modes section below. This script can take a while to complete so beyond the first test after start up you don't need to run this script. See the Section about Running additional tests below.
[[Image:StartingRADA initial.png|800px]]
=== Testing Modes ===
The RADA system has three testing modes: Robot Control Mode, Tuning Mode, and Box Step Mode. Additionally you can exit the execution at any time by pressing the ''Esc'' key. Once the terminal asks you to chose a mode you can use the following commands to enter the desired mode with a three second delay or exit the program. You can also use these commands to switch between the modes.
-''v'' : Enters the pendulum PID tuning mode, this will only really work when using PIDs to control the pendulum.
-''b'' : Enter Robot control mode, in this mode you can drive the robot around and the pendulum will try to stay vertical. This is the main mode used for testing the whole RADA system.
-''n'' : Enters box step mode, where the pendulum will change its desired pitch and roll angles every 20 seconds and move in a box shape.
-''Esc'' : By hitting the escape key the program will exit the program.
You will almost always want to run Robot Control Mode as the other modes are legacy modes from when we initially built and tested RADA and only works with the pendulum PID controllers. There are also a few utility commands that can be used in all modes.
-''2'' : Resets I composts of the Pitch/Roll PIDs and only the PIDs.
-''m'' : Adds a marker to the Log file incase odd things happen somewhere. This just increments a counter so if you use it look for changes in the marker value.
==== Robot Control Model ====
In Robot control mode you can control the motion of Eris. For PID control of Eris or 1D state feedback system the directional commands command Eris body velocity were for full system and Eris system state feedback controllers control the global velocity. All of these keys only need to be pressed not held down.
-''w'' : Moves Eris forward (+x) at some velocity depending on the controller.
-''s'' : Moves Eris in reverse (-x) at some velocity depending on the controller.
-''d'' : Moves Eris in right (+y) at some velocity depending on the controller.
-''a'' : Moves Eris in left (-y) at some velocity depending on the controller.
-''p'' : Stops the motion of Eris (Set all velocity set points to zero). I.e. if you hit ''w'' then hit ''s'' then Eris will be moving in reverse.
-''y'' : Moves Eris forward and to the right (+x/+y) simultaneously at some velocity depending on the controller.
-''t'' : Moves Eris forward and to the left (+x/-y) simultaneously at some velocity depending on the controller.
-''i'' : Moves Eris reverse and to the right (-x/+y) simultaneously at some velocity depending on the controller.
-''y'' : Moves Eris reverse and to the left (-x/-y) simultaneously at some velocity depending on the controller.
-''e'' : Rotate Eris clockwise (+yaw) at some angular rate. This only worked when RADA used the closed-loop FPGA control of the wheels. There is currently no controllers that use this command.
-''q'' : Rotate Eris counter-clockwise (-yaw) at some angular rate. This only worked when RADA used the closed-loop FPGA control of the wheels. There is currently no controllers that use this command.
-''<'' : Increment Eris' desired heading 45 degrees counter-clockwise (-yaw).
-''>'' : Increment Eris' desired heading 45 degrees clockwise (+yaw).
-''7'' : Increments the pitch set point (+pitch).
-''4'' : Decrements the pitch set point (-pitch).
-''8'' : Increments the roll set point (+roll).
-''5'' : Decrements the roll set point (-roll).
==== Tuning Mode ====
Tuning mode allows you to tune the PID controllers for both pitch and roll. The UI commands here are also available in Box Step Mode.
-''1'' : Tune the Pitch PID.
-''3'' : Tune the Roll PID.
-''7'' : Increase proportional gain of PID being tuned.
-''4'' : Decrease proportional gain of PID being tuned.
-''8'' : Increase integral gain of PID being tuned.
-''5'' : Decrease integral gain of PID being tuned.
-''9'' : Increase derivative gain of PID being tuned.
-''6'' : Decrease derivative gain of PID being tuned.
-''i'' : Increase set point of PID being tuned.
-''k'' : Decrease set point of PID being tuned.
-''o'' : Increase integral windup term of PID being tuned. (Not used)
-''l'' : Decrease integral windup term of PID being tuned. (Not used)
==== Box Step Mode ====
Box set mode will automatically change the set points of the pendulum every 20 seconds. The case statement for this mode can be changed for 1D and 2D step modes. This mode allows the user to use he same commands as Tuning Mode.
=== Running additional Tests ===
Once you have run one test with Eris on it is unnecessary to configure the FPGA or connect to the NFS server again. This is what took much of the time in the initial setup. This is what the script ''3_stat_eris.sh'' was developed for. It does everything that ''1_co3050-11.sh'' does but without reprogramming the FPGA or reconnecting to the NFS server. As a result it is ready to test much quicker.
Before starting the test it is best to have someone spotting the pendulum a holding it near vertical so that the pendulum doesn't have issues when entering a control mode.'''<span style="color:red"> Always run ensure the pendulum is spotted by a second person when testing so you don't hurt yourself, others in the lab, or the RADA system.</span>''' Once you spotter is ready run the shell scrip by= using the command ''./3_start_eris.sh'' in the terminal with the open SSH connection to Eris from the home, ''/root'', directory of Eris.
[[Image:StartingRADA2nd.png|800px]]
=== Locating and retrieving log files ===
If you are only demoing the system there is no need to go beyond this point. Once you are done with a test that you want to compare to the model you should retrieve the log file right away so you don't mix it up with other test. On CO3050-11 go to the dircetory ''/home/shared/MainProject/Logs'' using the file browser (you can do this in a terminal but it is easier from the file explorer). Once there, look for the folder that has been modified most recently as Eris date is normally out of sync with its date and time. Then look for the newest log file. Log files are named like ''log(hh.mm.ss).txt'' (ex. log(13.04.51).txt). This naming convention works well to ensure that no log file is over written but it isn't useful of describing what the test was of or for. Copy this log to the Desktop or to a USB drive and rename it. A good method is to name the file something like ''RADA_ctrl_otherNote#.txt'', where Describes what system you tested (ex. RADA, RADA1D, PEN1D, PEN2D), what typ of controller was used, other notes and then a number if this is a repeat of another test. This is much more useful when looking back at these logs later on. Before transferring the log file for processing you should record the wheel and propeller battery voltages in the header of the log file. The log file format is both human readable and can be parsed by MATALB. It was designed by the first RADA Senior Design Team and more information about the log files can be found [http://wikis.ece.iastate.edu/robotic-agriculture-data-acquisition/index.php/Data_Analysis_Tool here.] See he section below on measuring battery voltage below in order to get the best measurements for simulation of RADA.
=== Measuring battery voltages ===
The last thing that you need to do before simulating an experiment of the RADA platform is record the battery voltages for both the wheels and propellers. The wheel battery can be measured unloaded as there isn't large line losses between the battery and the H-bridges. The propeller battery voltage needs to be measured under load because the power cord running up the pendulum has significant line losses at the currents the propellers draw when in use. The battery voltages can be recorded in the log file for the test. Open the log file for the test you just completed (Use KWrite for Linux machines or Notepad++ for Windows machines). The first few lines of the log is the headder. It should look like this:
#Constants pitch_P pitch_I pitch_D
#PIDValues 48000 18000 21000
#Constants roll_P roll_I roll_D
#PIDValues 48000 18000 21000
#Battery Vquad Vwheels
#Voltage
Follow the procedure for measuring the voltage of each battery and then record the voltage under the corresponding battery. Then save the log file and close out of your text editor and the test will be ready for processing. Recoding the battery voltages in this way makes it much easier to find if you need the value latter. The final log file header should look like this once you are done
#Constants pitch_P pitch_I pitch_D
#PIDValues 48000 18000 21000
#Constants roll_P roll_I roll_D
#PIDValues 48000 18000 21000
#Battery Vquad Vwheels
#Voltage 14.44 8.257
==== Wheel Battery ====
1. After test disconnect wheel battery from the system.
2. Measure voltage of battery using multimeter.
[[Image:MeasureVwheel.jpg|800px]]
You can use the plug used for charging the 2-cell Lipos but make sure to connect the plug to the multimeter before connecting the battery and disconnect the battery before disconnecting the plug from the mulitmeter. It is generally the best practice to give the multimeter a few minutes to allow for the voltage measurement to stabilize as the battery measurement tends to be a little low right after the test. The multimeter will report data out to four decimal places it is best just to round to three decimal places for the wheel voltage.
==== Quad Battery ====
1. Setup code to run all four propellers at 50% throttle, uncomment the definition of ''mot50'' in main.cpp and compile the project.
2. Power off propellers by turning off the switch to the ESCs.
3. Connect multimeter to measure the voltage across one of the ESCs. This is done by using the power splitter cord.
-Connect one of the female XT60 connectors on the splitter to a male XT60 connector to banana connector cable.
-The banana connector connect to the hand held multimeter. The multimeter should be set to the 20VDC measurement setting.
-Next unplug one the ESCs' power connection.
-reconnect the ESC to power through the two remain connectors on the spliter cable.
4. Power on the propellers.
5. Run the system at 50% throttle and measure the steady-state voltage during the test. The battery will slow the voltage decay significantly, meaning it will keep the same measurement for a few seconds.
6. Stop the test and record the voltage in the log file. Make sure to disconnect the batter before removing the splitter cable.
{| class="wikitable" style="text-align:center"
|-
| [[Image:PowerSplitter.jpg|200px]]
| [[Image:QuadMultiCon.jpg |200px]]
| [[Image:QuadMultiSet.JPG |200px]]
| [[Image:QuadMeasESCcon.JPG|200px]]
|-
| Splitter cord.
| Connect splitter to multimeter.
| Settings for multimeter.
| Connecting ESC through splitter.
|}
The testing setup should look like the image below:
[[Image:QuadBattMeas.jpg|800px]]
== Post processing and Simulation ==
Simulating a test of RADA starts with processing and storing the data. Then all of the parameters of the model are loaded in the MATLAB Workspace. Finally the Simulink file used for the simulation is opened and the length of the simulation is set to match the length of the actual test. The simulation is run and the simulation output is stored. Finally the data should be plotted and compared.
=== Using the MATLAB data parsing tool ===
In depth discussion of how to use the log file parsing tool is described [http://wikis.ece.iastate.edu/robotic-agriculture-data-acquisition/index.php/Data_Analysis_Tool here.] I suggest using the version of the tool in the rada_resarch_project git repository Paul Uhing used for his Master's research. It con be found on CO3050-11 under the ucart account in the directory ''~/rada_research_project/DataAnalysiTool_omnicoor/Tool''. Simply open MATLAB and set the working directory to this file path. In the MATLAB Command Prompt run ''DataAnalysis''. A popup window should open up. Select the log file you want to process and wait for the tool to finish processing the file. Once this is complete there should be four structures in the MATLAB workspace.
-'''main''' : This contains all of the data extracted from the log file and the processing parameters used. main.expData contains two time structures: Time is used for the pendulum data and Eris_time is used for the ground vehicle data.
-'''X_ref''' : This contains the reference vector in m/s for x velocity that is feed into Simulink. This expedites the simulation setup process, this used to be done by hand.
-'''Y_ref''' : This contains the reference vector in m/s for y velocity that is feed into Simulink. This expedites the simulation setup process, this used to be done by hand.
-'''Yaw_ref''' : This contains the reference vector in radians for yaw that is feed into Simulink. This expedites the simulation setup process, this used to be done by hand. This one is new incase people start testing the system with heading changes but is not used in the current setup.
The first thing you should do is rename the main structure to the name you used for the log file. This is helpful for comparing multiple tests. Next you will want to crate two new variable ''Vquad_test'' an Vw_test''. In the MATLAB Command Prompt set the measured propeller voltage from the log file to ''Vquad_test'' and set the measured the wheel voltage to ''Vw_test'' as this will be used by the simulation. Finally if you did an open-loop test of the wheels create the variable ''Uol'' and set it to the open-loop wheel command used. Save all of these variables from the MATLAB workspace to a ''.mat'' file of the same name as log file you extracted the data from and save it in the same directory as your RADA Simulink files. As of August 2nd, 2016 this directory is ''~/rada_research_project/MATLAB/RADA.''
=== Setting up the MATLAB workspace for simulation ===
Change your MATLAB directory to this directory. Then run the simulation setup files. Currently you just need to run ''modelParams_smallWheels_RADA'' in the MATLAB Command Prompt. Next open the Simulink file with that contains the model of RADA controlled by the controller you tested.
-'''RADA_psiCtrl_v2_lqi_est.slx''' contains LQI, LQI+estimation, and LQG controller simulations.
-'''RADA_psiCtrl_v2.slx''' contains the PID controlled system.
-'''RADA_psiCtrl_v2_LQGsep.slx''' contains the subsystem LQG controlled system.
-'''RADA_psiCtrl_v2_LQGsep_ol.slx''' contains the simulation of the pendulum system controlled by an LQG and Eris controlled with open-loop commands.
Note all of the current (August 2nd, 2016) ''.slx'' files were created in MATLAB 2014b and will only work in MATLAB 2014B or newer. Then in the MATLAB Command Prompt type ''X_ref.time(end)'' exactly, don't add a semicolon, and hit enter. MATLAB will print the time of the last command in the X_ref structure. Set the en time of the simulation to this value and save your Simulink file.
=== Running simulations and storing results ===
Before running the simulation make sure that the simuation is using the ''ode23t'' differential equations solver. This system is a moderately stiff system of differential and the ''ode45'' solver doesn't do well with these types of systems. When using ''ode23t'' is should only take a few minutes to run a 100+ second simulation while doing the same test using ''ode45'' could take 8 hours. While this slow it is also bad for your hard drive as the simulation has to page between RAM and your computers hard drive a lot.
Once this check is done run the simulation. While it is running check what the output structures variables are named for for your RADA test system. Once the simulation is done go to your MATLAB Workspace and select all 15 outputs for your simulation or your sub-simulation if you used '''RADA_psiCtrl_v2_lqi_est.slx'''. Save these 15 output structures to a ''.mat'' file named as the log file with _sim appended to the end of the name.
The 15 outputs are structures containing a time vector and then the data from the simulation sampled at 100 Hz and the units of this data are the SI units (ex: radians, m/s). There is one output structure for x velocity, y velocity, x body velocity, y body velocity, theta (pitch), phi (roll), psi (yaw), and one per actuator command (ex: the command sent to a wheel). Now you have all the data you can plot it.
=== Plotting results ===
If you look at the ''DataSets'' folder below ''~/rada_research_project/MATLAB/RADA'' directory there are plenty of examples of how Paul Uhing compared simulation to test data. Generally you should grate a ''.m'' file with the same name as the log file this data was extracted from with _plot appended to the name.
Generally you can just copy an for RADA_LQG_compPID_plot.m RADA_PID_compLQG_plot.m, RADA_LQG_sep_plot.m, or RADA_LQG_sep_ol_plot.m files and rename the structures for your test.
These files create four figures. Figure 1 plots compares the x velocity data in the first sub figure and compares pitch (theta) data in the second sub figure. Figure 2 does the same thing as Figure 1 but with y velocity and roll data. Figure 3 looks at the yaw data. Finally, Figure 4 looks at the sample period between UAV and ERIS packets from the camera system just to check for periods of time with large packet drops.
You can follow a similar pattern to compare motor commands. Just make sure that you compare Quad Motor 2 from the test data with Quad Motor 4 from simulation and vise versa because propellers 2 and 4 were switch in Eris's software compared to the Model.
That is all you need to know for testing RADA against the model.
446f46a19dca6e95e0956ba3476fc055a89e7a28
332
331
2016-09-21T14:48:36Z
Jonessk
7
/* Connecting to RADA */
wikitext
text/x-wiki
This page will take you though setting up and testing RADA, retrieving the log file and other necessary data to run a simulation of that test and processing the data in MATLAB. Then actually running the simulation of RADA in Simulink. The initial setup and how to test the system can also be applied to demoing RADA.
== Setting Up a RADA Test ==
Testing RADA is not overly difficult once you get the hang of the steps to setup RADA. The following steps may seem like a long process to go from starting the testing process to having completed simulation and plotting of the test results but this whole test procedure (with the exception of battery charging) can be completed in about 15-20 minutes. These steps are meant to be as detailed as possible in order to help new users of RADA get up and running as quickly as possible.
'''<span style="color:red">NOTE: Always run RADA with at least 2 people!</span>''' The pendulum arm can crash into the ground if the network starts to drop packets and one person cannot give commands to RADA and spot the pendulum. This is a safety issue for both you and the RADA platform.
=== Charging Batteries ===
The lab currently uses mostly Hyperion batteries. We charge our batteries with a Hyperion EOS 1420i Net3 battery charger. For some general information about how to use this charger see [https://www.youtube.com/watch?v=-ox3EpzvsJ8 this video.]. In the lab we power this charger using the old Kepco Power supply because it is the only power supply that can supply enough current. Make sure that the power supply is set to an output voltage between 10.5V-29V.
{| class="wikitable" style="text-align:center"
|-
| [[Image:ChargerPowerSupplyOff.JPG|400px]]
| [[Image:ChargerPowerSuplyOn.JPG|400px]]
|-
| Kepco Power Supply off.
| Kepco Power Supply on with correct voltage supply range.
|}
The YouTube video link above should explain how to use the charger. RADA currently uses three different Lithium polymer (Lipo) batteries: 1600 mAh 2-cell Lipo for the wheels, 2600 mAh 2-cell Lipo for the electronics of Eris, and a 2600 mAh 4-cell Lipo for the propellers. The 1600 mAh 2-cell Lipo can be charged using memory slot 2 of the charger. The 2600 mAh 2-cell Lipos can be charged using memory slot 3 for fast charging and memory slot 4 for slower charging (use this if the battery voltage drops really low for 10-20 minutes then switch to fast charging). The 2600 mAh 4-cell Lipo can be charged using memory slot 8. The 1600 mAh 2-cell and 2600 mAh 4-cell generally charge in 10-20 minutes apiece while the 2600 mAh 2-cell generally take up to 70 minutes to charge fully.
=== Setting up the Camera System ===
The camera system is run on the windows computer CO3050-07. You can log into this computer using a local microcart username and password (not posted here for security reasons, but any one who works in the lab should know it). Once logged in, look for Tracking Tools in the start menu or look for the shortcut shown below:
[[Image:TrackingTools_shortcut.PNG|thumb|center|Tracking Tools shortcut]]
Once the program opens the screen should look something like this:
[[Image:NewTrackingTools.PNG|800px]]
In the Tracking Tools Quick Start pop up menu select Open Existing Project and then navigate to ''D:\Optitrack_Configuration'' (It should open to this directory by default) and select the most recent Tracking Tools project. It should have the naming scheme ''TrackingToolsProject YYYY-MM-DD timeStamp.ttp''. This is normally the most recently edited file when sorting by date modified. The most recent one as of August 1st, 2016 is ''TrackingToolsProject 2015-09-23 2.30pm.ttp''.
[[Image:OpeningProject.PNG|800px]]
You should notice that the cameras shown in the main project screen arrange themselves like the camera system configuration once the project has been opened. Now the constellations need to be loaded. This can be done by going to ''File->Open'' and another popup window will open. Navigate back to ''D:\Optitrack_Configuration'' (It should open to this directory by default) and select the most recently dated set of RADA trackables. They have the naming scheme ''RADA_entireSystem_M_D_YYYY.tra''. The most recent one as of August 1st, 2016 is ''RADA_entireSystem_7_8_2016.tra''.
[[Image:Opening_trackables.PNG|800px]]
Once the project and trackables are open, the cameras should appear in their constellation (square) and there should be two constellations under ''Project Explorer->Trackables''. One named UAV for the pendulum and one named ERIS for the ground vehicle. In order to get additional information about each constellation, left click on the the name of the desired trackable.
[[Image:SelectingUAV.PNG|800px]]
Once a trackable is selected more information about it is available in the ''Trackables'' Tab on the right side of the screen. For the current position and orientation look at the ''Real-Time Info'' sub-tab. This gives the orientation in the wrong order for how we currently use the Euler angles. When two or three of the angles are near zero you can switch yaw and pitch to get roughly the correct orientation.
[[Image:Uav_realTimeInfo.PNG|800px]]
Now we need check to make sure the system is zeroed.
1. Hold RADA so that the front of the ground robot (ERIS is facing the wall with the white boards (east)). The front side of Eris is labeled. If it isn't, the front is the side opposite the switches and the side with the trackable constellation on it.
2. Make sure that the motor with the red motor mount is also facing the wall with the white boards.
3. Make sure the quad system is aligned along Eris Axis by standing behind the system. If the system is aligned, you should be able to block the mounting bolts of the front propeller motor with the pole while facing the east wall.
4. While holding the pendulum approximately vertical, see if the camera system reads zeros for the pendulum (UAV) pitch and roll (yaw and roll in ''Real-Time Info''). If yaw is off by a few degrees that is fine.
5. Compare the yaw of the UAV to that of ERIS (Remember this is pitch in ''Real-Time Info''). If they are both near zero and within a few degrees and the pendulum's pitch/roll were also near zero then you are ready to use the camera system. Otherwise, go to the next step.
6. You need to zero the pendulum.
- Align ERIS so it is near zero yaw first (eye ball it).
- Get a level and a friend. Have your friend use a level to ensure that the pendulum is level in both directions and hold it there.
- With the UAV constellation selected go to the ''Orientation'' tab (next to ''Real-Time Info'' tab) and click on ''Reset To Current Orientation button''
- Now your friend can set the pendulum down and you can zero ERIS the same way.
7. Save the new trackable orientation by going to ''File->Save Trackables...'' and save a file using the same naming conventions as the trackable file you opened earlier. Use the current data so you don't have to re-zero the system the next time you test.
[[Image:Uav_ResetOrientation.PNG|800px]]
=== Building Software ===
The development environment for running RADA is hosted on CO3050-11, a Linux Red Hat environment. This computer has a local ucart user name that you should use (the password isn't put here for security reasons). First, ensure that the RADA software is setup correctly for the test you want to run. To do this, you will need to open the main.cpp and logger.cpp files and make sure all of the compile time macros you want are defined correctly. All of the c++ files you should need to edit are in the directory ''~/Desktop/rada_research_project/ErisResearchCode/CppProjects/MainProgram_PacketLoss/src/Korebot'' Below are compiler macro options for main.cpp:
-'''H2ctrl''' : This will cause the system to enter H2 controller mode where the whole RADA system is controlled by an H2 controller.
-'''ssTracking''' : H2ctrl must also be defined for this macro to do anything. This macro will has the system to be controlled by a tracking H2 controller.
-'''ssMotors''' : H2ctrl must also be defined for this macro to do anything. This macro will has the system to be controlled by an H2 contorller that contains propeller states. This also causes the system to "Dance."
-'''ssDrop''' : Cause the system to go into packet drop controller mode. This mode allows controllers designed for lossy networks to be tested. Based off of other definitions how lossy the network is can be simulated. If nothing else is defined this controller becomes basically a H2 controller.
-'''drop10''' : Will put the packet drop mode into 10% loss mode and use a controller designed for 10% loss.
-'''drop30''' : Will put the packet drop mode into 30% loss mode and use a controller designed for 30% loss.
-'''drop50''' : Will put the packet drop mode into 50% loss mode and use a controller designed for 50% loss.
-'''mot50''' : This macro over-rides all other macros. If this is turned on the wheels will not run and the propellers will be run at 50% command. This is used for measuring the effective battery voltage seen by the ESCs. This is always run after a test.
-'''RADAlqi''' : This macro will cause the system to use an LQI controller on the whole system. The linear velocity states are calculated with no filter and the angular velocity states are calculated with filters.
-'''RADAlqi_est''' : This macro will cause the system to use an LQI controller on the whole system. A traditional estimator is used to estimate the states.
-'''rada_lqg''' : This macro will cause the entire system to be controlled by an LQG controller/estimator system.
-'''rada_split_lqg''' : This macro will cause the pendulum and ground robot to be controlled by their own LQG systems.
-'''rada_split_lqg_ol''' : This macro will cause the pendulum to be controlled by an LQG controller, the yaw of the ground robot to be controlled by a PID controller, and the ground robot linear velocities to be controlled with open-loop commands.
-'''yaw_off''' : This macro will cause the yaw control to be disabled on some controllers.
*'''accR''' : This macro will cause the PID linear velocity controllers to be given ramps to accelerate from one velocity to another instead of steps.
-'''posRamp''' : This macro will cause the linear velocities of RADA to be controlled by position PIDs with ramp reference instead of velocity commands.
-If no controller selection is made all controllers revert to PID controllers
All of these macros can be defined simply by uncommenting the corresponding define statement in main.cpp. The macros in the logger.cpp can be seen below:
-'''ssDrop''' : This macro puts the logger into packet drop controller mode and logs the correct values for the packet drop controllers.
-'''RADAlqi''' : This macro puts the logger into full system LQI controller logging mode.
-'''RADAlqi_est''' : This macro puts the logger into full system LQI controller plus estimator logging mode.
-'''rada_lqg''' : This puts the logger into full system LQG controller logging mode.
-'''rada_split_lqg''' : This macro causes the logger to log data about the subsystem LQG controllers.
-'''rada_split_lqg_ol''' : This cause the system to log data about the pendulum LQG system and the open-loop linear velocity commands.
-'''H2ctrl''' : This macro causes the logger to log data about the full system H2 controllers.
-If no logging mode is selected then the logger will default to logging PID data.
Because the system only calculates controllers for one set of controllers it is important to ensure that the logger is in the correct mode based off of what is defined in main.cpp. As of August 1st, 2016 the defines in main.cpp are not seen in logger.cpp.
Finally in a command prompt navigate to the driectroy: ''~/Desktop/rada_research_project/ErisResearchCode/CppProjects/MainProgram_PacketLoss''
Here just type: ''make''. The code will compile for your desired mode. For setting up a new development directory see [http://wikis.ece.iastate.edu/robotic-agriculture-data-acquisition/index.php/Setting_up_a_new_development_environment Setting up a new development environment] from the RADA Senior Design wiki.
[[Image:ComplingRADACode.png|800px]]
The complied executable code ends up in ''/home/shared/MainProject''. The ''/home/shared'' directory is setup as a network file share (NFS).
[[Image:ErisCompliedCode-config.png|800px]]
This service needs to be restarted when CO3050-11 is restarted. [http://wikis.ece.iastate.edu/robotic-agriculture-data-acquisition/index.php/Configuring_NFS_shares_for_the_robot Configure NFS shares for the robot] from the RADA Senior Design wiki. Be sure to use the new Linux install command in step six. Though I have found that even on a good strt the ''[ok]'' messages will still print.
=== Turning on RADA ===
Turning on Eris is fairly simple. Each system has its own battery. There is one for the wheels that plugs in at the front of Eris (opposite side of the switches), one for the electronics in the back of Eris (in between the switches), and one for the propellers that goes on top of Eris.
[[Image:ErisOnPhoto.jpg|800px]]
The wheel battery is normally 1600 mAh 2-cell Lipo but any 2-cell Lipo will work. The wheels are turned on by flipping the silver switch so the top points away from the system. The electronics normally use a 2600 mAh 2-cell Lipo. The electronics are turned on by flipping the green switch away from the system. It is important that you use EITHER the WIFI adapter OR hardwired Ethernet, because the VRPN may listen to the camera data broadcast over both connections which could cause problems. The propeller system is powered via a 2600 mAh 4-cell Lipo that connects to a power cable at the base of the pendulum. There is a switch to turn on the power to the propellers system. You will know it is on when the 1 on the switch is flush with the switch housing instead of sticking out. It takes about 30 seconds to a minute for Eris to boot up and start the networking connections. When the WIFI is plugged in, you will know it is ready when a blue light turns on, on the module.
=== Connecting to RADA ===
RADA is controlled through an SSH connection. in a commands prompt, not the one you compile the code from so that you can recompile for different setup without needing to close the connection. If you are using a WIFI connection use the command ''ssh root@192.168.0.53''. If you are connected to Eris through a LAN connection use the command ''ssh root@192.168.0.54''. If the connection goes though you should be prompted for a password.
The password is ''rootme''.
[[Image:Ssh2Eris.png|800px]]
It is important to close the SSH connection before turning off Eris because the terminal you are using will hang up if you don't. You can close the connection by using the command ''exit''.
[[Image:ClosingSSH.png|800px]]
== Testing RADA ==
Now that you are connected to Eris you can run tests. The testing is started by a few different methods.
=== Running the first test after power up ===
For the firs test after powering on Eris a few additional steps need to be completed in order to test the system. The FPGA motor controller needs to be programmed and Eris needs to connect the the NFS server running on CO3050-11. This is accomplished by running ''1_co3050-11.sh'', this shell scrip will setup the NFS, load the bit file into the FPGA configuration memory. Then it retrieves the executable file from the NFS server ''/mnt/nfs/MainProject and runs the executable. Once the user exits the executable the log file produces is copied from the ''~/Logs/YYYY_MM_DD_Day'' directory on Eris to ''/home/shared/MainProject/Logs/YYYY_MM_DD_Day'' on CO3050-11. When the folder for the current Eris date doesn't exist it creates this directory in CO3050-11 and then removes the directory and log file from Eris. You may see an warning that when coping the log file Eris couldn't maintain the file permisiion settings. This is normal as Eris doesn't have the same access to the NSF server as it has to its own files. This Date stamp uses date on Eris which is currently in June of 2008 as of August 2nd, 2016.
Before starting the test it is best to have someone spotting the pendulum a holding it near vertical so that the pendulum doesn't have issues when entering a control mode.'''<span style="color:red"> Always run ensure the pendulum is spotted by a second person when testing so you don't hurt yourself, others in the lab, or the RADA system.</span>''' Once you spotter is ready run the shell scrip by= using the command ''./1_co3050-11.sh'' in the terminal with the open SSH connection to Eris from the home, ''/root'', directory of Eris. When you run this script there will be a bunch of information printed out about the PIC bus and loading the bit file to configure the FPGA, you will know that RADA is ready for the test when it asks you to select a running mode. See the Testing Modes section below. This script can take a while to complete so beyond the first test after start up you don't need to run this script. See the Section about Running additional tests below.
[[Image:StartingRADA initial.png|800px]]
=== Testing Modes ===
The RADA system has three testing modes: Robot Control Mode, Tuning Mode, and Box Step Mode. Additionally you can exit the execution at any time by pressing the ''Esc'' key. Once the terminal asks you to chose a mode you can use the following commands to enter the desired mode with a three second delay or exit the program. You can also use these commands to switch between the modes.
-''v'' : Enters the pendulum PID tuning mode, this will only really work when using PIDs to control the pendulum.
-''b'' : Enter Robot control mode, in this mode you can drive the robot around and the pendulum will try to stay vertical. This is the main mode used for testing the whole RADA system.
-''n'' : Enters box step mode, where the pendulum will change its desired pitch and roll angles every 20 seconds and move in a box shape.
-''Esc'' : By hitting the escape key the program will exit the program.
You will almost always want to run Robot Control Mode as the other modes are legacy modes from when we initially built and tested RADA and only works with the pendulum PID controllers. There are also a few utility commands that can be used in all modes.
-''2'' : Resets I composts of the Pitch/Roll PIDs and only the PIDs.
-''m'' : Adds a marker to the Log file incase odd things happen somewhere. This just increments a counter so if you use it look for changes in the marker value.
==== Robot Control Model ====
In Robot control mode you can control the motion of Eris. For PID control of Eris or 1D state feedback system the directional commands command Eris body velocity were for full system and Eris system state feedback controllers control the global velocity. All of these keys only need to be pressed not held down.
-''w'' : Moves Eris forward (+x) at some velocity depending on the controller.
-''s'' : Moves Eris in reverse (-x) at some velocity depending on the controller.
-''d'' : Moves Eris in right (+y) at some velocity depending on the controller.
-''a'' : Moves Eris in left (-y) at some velocity depending on the controller.
-''p'' : Stops the motion of Eris (Set all velocity set points to zero). I.e. if you hit ''w'' then hit ''s'' then Eris will be moving in reverse.
-''y'' : Moves Eris forward and to the right (+x/+y) simultaneously at some velocity depending on the controller.
-''t'' : Moves Eris forward and to the left (+x/-y) simultaneously at some velocity depending on the controller.
-''i'' : Moves Eris reverse and to the right (-x/+y) simultaneously at some velocity depending on the controller.
-''y'' : Moves Eris reverse and to the left (-x/-y) simultaneously at some velocity depending on the controller.
-''e'' : Rotate Eris clockwise (+yaw) at some angular rate. This only worked when RADA used the closed-loop FPGA control of the wheels. There is currently no controllers that use this command.
-''q'' : Rotate Eris counter-clockwise (-yaw) at some angular rate. This only worked when RADA used the closed-loop FPGA control of the wheels. There is currently no controllers that use this command.
-''<'' : Increment Eris' desired heading 45 degrees counter-clockwise (-yaw).
-''>'' : Increment Eris' desired heading 45 degrees clockwise (+yaw).
-''7'' : Increments the pitch set point (+pitch).
-''4'' : Decrements the pitch set point (-pitch).
-''8'' : Increments the roll set point (+roll).
-''5'' : Decrements the roll set point (-roll).
==== Tuning Mode ====
Tuning mode allows you to tune the PID controllers for both pitch and roll. The UI commands here are also available in Box Step Mode.
-''1'' : Tune the Pitch PID.
-''3'' : Tune the Roll PID.
-''7'' : Increase proportional gain of PID being tuned.
-''4'' : Decrease proportional gain of PID being tuned.
-''8'' : Increase integral gain of PID being tuned.
-''5'' : Decrease integral gain of PID being tuned.
-''9'' : Increase derivative gain of PID being tuned.
-''6'' : Decrease derivative gain of PID being tuned.
-''i'' : Increase set point of PID being tuned.
-''k'' : Decrease set point of PID being tuned.
-''o'' : Increase integral windup term of PID being tuned. (Not used)
-''l'' : Decrease integral windup term of PID being tuned. (Not used)
==== Box Step Mode ====
Box set mode will automatically change the set points of the pendulum every 20 seconds. The case statement for this mode can be changed for 1D and 2D step modes. This mode allows the user to use he same commands as Tuning Mode.
=== Running additional Tests ===
Once you have run one test with Eris on it is unnecessary to configure the FPGA or connect to the NFS server again. This is what took much of the time in the initial setup. This is what the script ''3_stat_eris.sh'' was developed for. It does everything that ''1_co3050-11.sh'' does but without reprogramming the FPGA or reconnecting to the NFS server. As a result it is ready to test much quicker.
Before starting the test it is best to have someone spotting the pendulum a holding it near vertical so that the pendulum doesn't have issues when entering a control mode.'''<span style="color:red"> Always run ensure the pendulum is spotted by a second person when testing so you don't hurt yourself, others in the lab, or the RADA system.</span>''' Once you spotter is ready run the shell scrip by= using the command ''./3_start_eris.sh'' in the terminal with the open SSH connection to Eris from the home, ''/root'', directory of Eris.
[[Image:StartingRADA2nd.png|800px]]
=== Locating and retrieving log files ===
If you are only demoing the system there is no need to go beyond this point. Once you are done with a test that you want to compare to the model you should retrieve the log file right away so you don't mix it up with other test. On CO3050-11 go to the dircetory ''/home/shared/MainProject/Logs'' using the file browser (you can do this in a terminal but it is easier from the file explorer). Once there, look for the folder that has been modified most recently as Eris date is normally out of sync with its date and time. Then look for the newest log file. Log files are named like ''log(hh.mm.ss).txt'' (ex. log(13.04.51).txt). This naming convention works well to ensure that no log file is over written but it isn't useful of describing what the test was of or for. Copy this log to the Desktop or to a USB drive and rename it. A good method is to name the file something like ''RADA_ctrl_otherNote#.txt'', where Describes what system you tested (ex. RADA, RADA1D, PEN1D, PEN2D), what typ of controller was used, other notes and then a number if this is a repeat of another test. This is much more useful when looking back at these logs later on. Before transferring the log file for processing you should record the wheel and propeller battery voltages in the header of the log file. The log file format is both human readable and can be parsed by MATALB. It was designed by the first RADA Senior Design Team and more information about the log files can be found [http://wikis.ece.iastate.edu/robotic-agriculture-data-acquisition/index.php/Data_Analysis_Tool here.] See he section below on measuring battery voltage below in order to get the best measurements for simulation of RADA.
=== Measuring battery voltages ===
The last thing that you need to do before simulating an experiment of the RADA platform is record the battery voltages for both the wheels and propellers. The wheel battery can be measured unloaded as there isn't large line losses between the battery and the H-bridges. The propeller battery voltage needs to be measured under load because the power cord running up the pendulum has significant line losses at the currents the propellers draw when in use. The battery voltages can be recorded in the log file for the test. Open the log file for the test you just completed (Use KWrite for Linux machines or Notepad++ for Windows machines). The first few lines of the log is the headder. It should look like this:
#Constants pitch_P pitch_I pitch_D
#PIDValues 48000 18000 21000
#Constants roll_P roll_I roll_D
#PIDValues 48000 18000 21000
#Battery Vquad Vwheels
#Voltage
Follow the procedure for measuring the voltage of each battery and then record the voltage under the corresponding battery. Then save the log file and close out of your text editor and the test will be ready for processing. Recoding the battery voltages in this way makes it much easier to find if you need the value latter. The final log file header should look like this once you are done
#Constants pitch_P pitch_I pitch_D
#PIDValues 48000 18000 21000
#Constants roll_P roll_I roll_D
#PIDValues 48000 18000 21000
#Battery Vquad Vwheels
#Voltage 14.44 8.257
==== Wheel Battery ====
1. After test disconnect wheel battery from the system.
2. Measure voltage of battery using multimeter.
[[Image:MeasureVwheel.jpg|800px]]
You can use the plug used for charging the 2-cell Lipos but make sure to connect the plug to the multimeter before connecting the battery and disconnect the battery before disconnecting the plug from the mulitmeter. It is generally the best practice to give the multimeter a few minutes to allow for the voltage measurement to stabilize as the battery measurement tends to be a little low right after the test. The multimeter will report data out to four decimal places it is best just to round to three decimal places for the wheel voltage.
==== Quad Battery ====
1. Setup code to run all four propellers at 50% throttle, uncomment the definition of ''mot50'' in main.cpp and compile the project.
2. Power off propellers by turning off the switch to the ESCs.
3. Connect multimeter to measure the voltage across one of the ESCs. This is done by using the power splitter cord.
-Connect one of the female XT60 connectors on the splitter to a male XT60 connector to banana connector cable.
-The banana connector connect to the hand held multimeter. The multimeter should be set to the 20VDC measurement setting.
-Next unplug one the ESCs' power connection.
-reconnect the ESC to power through the two remain connectors on the spliter cable.
4. Power on the propellers.
5. Run the system at 50% throttle and measure the steady-state voltage during the test. The battery will slow the voltage decay significantly, meaning it will keep the same measurement for a few seconds.
6. Stop the test and record the voltage in the log file. Make sure to disconnect the batter before removing the splitter cable.
{| class="wikitable" style="text-align:center"
|-
| [[Image:PowerSplitter.jpg|200px]]
| [[Image:QuadMultiCon.jpg |200px]]
| [[Image:QuadMultiSet.JPG |200px]]
| [[Image:QuadMeasESCcon.JPG|200px]]
|-
| Splitter cord.
| Connect splitter to multimeter.
| Settings for multimeter.
| Connecting ESC through splitter.
|}
The testing setup should look like the image below:
[[Image:QuadBattMeas.jpg|800px]]
== Post processing and Simulation ==
Simulating a test of RADA starts with processing and storing the data. Then all of the parameters of the model are loaded in the MATLAB Workspace. Finally the Simulink file used for the simulation is opened and the length of the simulation is set to match the length of the actual test. The simulation is run and the simulation output is stored. Finally the data should be plotted and compared.
=== Using the MATLAB data parsing tool ===
In depth discussion of how to use the log file parsing tool is described [http://wikis.ece.iastate.edu/robotic-agriculture-data-acquisition/index.php/Data_Analysis_Tool here.] I suggest using the version of the tool in the rada_resarch_project git repository Paul Uhing used for his Master's research. It con be found on CO3050-11 under the ucart account in the directory ''~/rada_research_project/DataAnalysiTool_omnicoor/Tool''. Simply open MATLAB and set the working directory to this file path. In the MATLAB Command Prompt run ''DataAnalysis''. A popup window should open up. Select the log file you want to process and wait for the tool to finish processing the file. Once this is complete there should be four structures in the MATLAB workspace.
-'''main''' : This contains all of the data extracted from the log file and the processing parameters used. main.expData contains two time structures: Time is used for the pendulum data and Eris_time is used for the ground vehicle data.
-'''X_ref''' : This contains the reference vector in m/s for x velocity that is feed into Simulink. This expedites the simulation setup process, this used to be done by hand.
-'''Y_ref''' : This contains the reference vector in m/s for y velocity that is feed into Simulink. This expedites the simulation setup process, this used to be done by hand.
-'''Yaw_ref''' : This contains the reference vector in radians for yaw that is feed into Simulink. This expedites the simulation setup process, this used to be done by hand. This one is new incase people start testing the system with heading changes but is not used in the current setup.
The first thing you should do is rename the main structure to the name you used for the log file. This is helpful for comparing multiple tests. Next you will want to crate two new variable ''Vquad_test'' an Vw_test''. In the MATLAB Command Prompt set the measured propeller voltage from the log file to ''Vquad_test'' and set the measured the wheel voltage to ''Vw_test'' as this will be used by the simulation. Finally if you did an open-loop test of the wheels create the variable ''Uol'' and set it to the open-loop wheel command used. Save all of these variables from the MATLAB workspace to a ''.mat'' file of the same name as log file you extracted the data from and save it in the same directory as your RADA Simulink files. As of August 2nd, 2016 this directory is ''~/rada_research_project/MATLAB/RADA.''
=== Setting up the MATLAB workspace for simulation ===
Change your MATLAB directory to this directory. Then run the simulation setup files. Currently you just need to run ''modelParams_smallWheels_RADA'' in the MATLAB Command Prompt. Next open the Simulink file with that contains the model of RADA controlled by the controller you tested.
-'''RADA_psiCtrl_v2_lqi_est.slx''' contains LQI, LQI+estimation, and LQG controller simulations.
-'''RADA_psiCtrl_v2.slx''' contains the PID controlled system.
-'''RADA_psiCtrl_v2_LQGsep.slx''' contains the subsystem LQG controlled system.
-'''RADA_psiCtrl_v2_LQGsep_ol.slx''' contains the simulation of the pendulum system controlled by an LQG and Eris controlled with open-loop commands.
Note all of the current (August 2nd, 2016) ''.slx'' files were created in MATLAB 2014b and will only work in MATLAB 2014B or newer. Then in the MATLAB Command Prompt type ''X_ref.time(end)'' exactly, don't add a semicolon, and hit enter. MATLAB will print the time of the last command in the X_ref structure. Set the en time of the simulation to this value and save your Simulink file.
=== Running simulations and storing results ===
Before running the simulation make sure that the simuation is using the ''ode23t'' differential equations solver. This system is a moderately stiff system of differential and the ''ode45'' solver doesn't do well with these types of systems. When using ''ode23t'' is should only take a few minutes to run a 100+ second simulation while doing the same test using ''ode45'' could take 8 hours. While this slow it is also bad for your hard drive as the simulation has to page between RAM and your computers hard drive a lot.
Once this check is done run the simulation. While it is running check what the output structures variables are named for for your RADA test system. Once the simulation is done go to your MATLAB Workspace and select all 15 outputs for your simulation or your sub-simulation if you used '''RADA_psiCtrl_v2_lqi_est.slx'''. Save these 15 output structures to a ''.mat'' file named as the log file with _sim appended to the end of the name.
The 15 outputs are structures containing a time vector and then the data from the simulation sampled at 100 Hz and the units of this data are the SI units (ex: radians, m/s). There is one output structure for x velocity, y velocity, x body velocity, y body velocity, theta (pitch), phi (roll), psi (yaw), and one per actuator command (ex: the command sent to a wheel). Now you have all the data you can plot it.
=== Plotting results ===
If you look at the ''DataSets'' folder below ''~/rada_research_project/MATLAB/RADA'' directory there are plenty of examples of how Paul Uhing compared simulation to test data. Generally you should grate a ''.m'' file with the same name as the log file this data was extracted from with _plot appended to the name.
Generally you can just copy an for RADA_LQG_compPID_plot.m RADA_PID_compLQG_plot.m, RADA_LQG_sep_plot.m, or RADA_LQG_sep_ol_plot.m files and rename the structures for your test.
These files create four figures. Figure 1 plots compares the x velocity data in the first sub figure and compares pitch (theta) data in the second sub figure. Figure 2 does the same thing as Figure 1 but with y velocity and roll data. Figure 3 looks at the yaw data. Finally, Figure 4 looks at the sample period between UAV and ERIS packets from the camera system just to check for periods of time with large packet drops.
You can follow a similar pattern to compare motor commands. Just make sure that you compare Quad Motor 2 from the test data with Quad Motor 4 from simulation and vise versa because propellers 2 and 4 were switch in Eris's software compared to the Model.
That is all you need to know for testing RADA against the model.
3fb26c626a752c3855ddd56a5896efdc9495d768
333
332
2016-09-21T14:53:51Z
Jonessk
7
/* Running the first test after power up */
wikitext
text/x-wiki
This page will take you though setting up and testing RADA, retrieving the log file and other necessary data to run a simulation of that test and processing the data in MATLAB. Then actually running the simulation of RADA in Simulink. The initial setup and how to test the system can also be applied to demoing RADA.
== Setting Up a RADA Test ==
Testing RADA is not overly difficult once you get the hang of the steps to setup RADA. The following steps may seem like a long process to go from starting the testing process to having completed simulation and plotting of the test results but this whole test procedure (with the exception of battery charging) can be completed in about 15-20 minutes. These steps are meant to be as detailed as possible in order to help new users of RADA get up and running as quickly as possible.
'''<span style="color:red">NOTE: Always run RADA with at least 2 people!</span>''' The pendulum arm can crash into the ground if the network starts to drop packets and one person cannot give commands to RADA and spot the pendulum. This is a safety issue for both you and the RADA platform.
=== Charging Batteries ===
The lab currently uses mostly Hyperion batteries. We charge our batteries with a Hyperion EOS 1420i Net3 battery charger. For some general information about how to use this charger see [https://www.youtube.com/watch?v=-ox3EpzvsJ8 this video.]. In the lab we power this charger using the old Kepco Power supply because it is the only power supply that can supply enough current. Make sure that the power supply is set to an output voltage between 10.5V-29V.
{| class="wikitable" style="text-align:center"
|-
| [[Image:ChargerPowerSupplyOff.JPG|400px]]
| [[Image:ChargerPowerSuplyOn.JPG|400px]]
|-
| Kepco Power Supply off.
| Kepco Power Supply on with correct voltage supply range.
|}
The YouTube video link above should explain how to use the charger. RADA currently uses three different Lithium polymer (Lipo) batteries: 1600 mAh 2-cell Lipo for the wheels, 2600 mAh 2-cell Lipo for the electronics of Eris, and a 2600 mAh 4-cell Lipo for the propellers. The 1600 mAh 2-cell Lipo can be charged using memory slot 2 of the charger. The 2600 mAh 2-cell Lipos can be charged using memory slot 3 for fast charging and memory slot 4 for slower charging (use this if the battery voltage drops really low for 10-20 minutes then switch to fast charging). The 2600 mAh 4-cell Lipo can be charged using memory slot 8. The 1600 mAh 2-cell and 2600 mAh 4-cell generally charge in 10-20 minutes apiece while the 2600 mAh 2-cell generally take up to 70 minutes to charge fully.
=== Setting up the Camera System ===
The camera system is run on the windows computer CO3050-07. You can log into this computer using a local microcart username and password (not posted here for security reasons, but any one who works in the lab should know it). Once logged in, look for Tracking Tools in the start menu or look for the shortcut shown below:
[[Image:TrackingTools_shortcut.PNG|thumb|center|Tracking Tools shortcut]]
Once the program opens the screen should look something like this:
[[Image:NewTrackingTools.PNG|800px]]
In the Tracking Tools Quick Start pop up menu select Open Existing Project and then navigate to ''D:\Optitrack_Configuration'' (It should open to this directory by default) and select the most recent Tracking Tools project. It should have the naming scheme ''TrackingToolsProject YYYY-MM-DD timeStamp.ttp''. This is normally the most recently edited file when sorting by date modified. The most recent one as of August 1st, 2016 is ''TrackingToolsProject 2015-09-23 2.30pm.ttp''.
[[Image:OpeningProject.PNG|800px]]
You should notice that the cameras shown in the main project screen arrange themselves like the camera system configuration once the project has been opened. Now the constellations need to be loaded. This can be done by going to ''File->Open'' and another popup window will open. Navigate back to ''D:\Optitrack_Configuration'' (It should open to this directory by default) and select the most recently dated set of RADA trackables. They have the naming scheme ''RADA_entireSystem_M_D_YYYY.tra''. The most recent one as of August 1st, 2016 is ''RADA_entireSystem_7_8_2016.tra''.
[[Image:Opening_trackables.PNG|800px]]
Once the project and trackables are open, the cameras should appear in their constellation (square) and there should be two constellations under ''Project Explorer->Trackables''. One named UAV for the pendulum and one named ERIS for the ground vehicle. In order to get additional information about each constellation, left click on the the name of the desired trackable.
[[Image:SelectingUAV.PNG|800px]]
Once a trackable is selected more information about it is available in the ''Trackables'' Tab on the right side of the screen. For the current position and orientation look at the ''Real-Time Info'' sub-tab. This gives the orientation in the wrong order for how we currently use the Euler angles. When two or three of the angles are near zero you can switch yaw and pitch to get roughly the correct orientation.
[[Image:Uav_realTimeInfo.PNG|800px]]
Now we need check to make sure the system is zeroed.
1. Hold RADA so that the front of the ground robot (ERIS is facing the wall with the white boards (east)). The front side of Eris is labeled. If it isn't, the front is the side opposite the switches and the side with the trackable constellation on it.
2. Make sure that the motor with the red motor mount is also facing the wall with the white boards.
3. Make sure the quad system is aligned along Eris Axis by standing behind the system. If the system is aligned, you should be able to block the mounting bolts of the front propeller motor with the pole while facing the east wall.
4. While holding the pendulum approximately vertical, see if the camera system reads zeros for the pendulum (UAV) pitch and roll (yaw and roll in ''Real-Time Info''). If yaw is off by a few degrees that is fine.
5. Compare the yaw of the UAV to that of ERIS (Remember this is pitch in ''Real-Time Info''). If they are both near zero and within a few degrees and the pendulum's pitch/roll were also near zero then you are ready to use the camera system. Otherwise, go to the next step.
6. You need to zero the pendulum.
- Align ERIS so it is near zero yaw first (eye ball it).
- Get a level and a friend. Have your friend use a level to ensure that the pendulum is level in both directions and hold it there.
- With the UAV constellation selected go to the ''Orientation'' tab (next to ''Real-Time Info'' tab) and click on ''Reset To Current Orientation button''
- Now your friend can set the pendulum down and you can zero ERIS the same way.
7. Save the new trackable orientation by going to ''File->Save Trackables...'' and save a file using the same naming conventions as the trackable file you opened earlier. Use the current data so you don't have to re-zero the system the next time you test.
[[Image:Uav_ResetOrientation.PNG|800px]]
=== Building Software ===
The development environment for running RADA is hosted on CO3050-11, a Linux Red Hat environment. This computer has a local ucart user name that you should use (the password isn't put here for security reasons). First, ensure that the RADA software is setup correctly for the test you want to run. To do this, you will need to open the main.cpp and logger.cpp files and make sure all of the compile time macros you want are defined correctly. All of the c++ files you should need to edit are in the directory ''~/Desktop/rada_research_project/ErisResearchCode/CppProjects/MainProgram_PacketLoss/src/Korebot'' Below are compiler macro options for main.cpp:
-'''H2ctrl''' : This will cause the system to enter H2 controller mode where the whole RADA system is controlled by an H2 controller.
-'''ssTracking''' : H2ctrl must also be defined for this macro to do anything. This macro will has the system to be controlled by a tracking H2 controller.
-'''ssMotors''' : H2ctrl must also be defined for this macro to do anything. This macro will has the system to be controlled by an H2 contorller that contains propeller states. This also causes the system to "Dance."
-'''ssDrop''' : Cause the system to go into packet drop controller mode. This mode allows controllers designed for lossy networks to be tested. Based off of other definitions how lossy the network is can be simulated. If nothing else is defined this controller becomes basically a H2 controller.
-'''drop10''' : Will put the packet drop mode into 10% loss mode and use a controller designed for 10% loss.
-'''drop30''' : Will put the packet drop mode into 30% loss mode and use a controller designed for 30% loss.
-'''drop50''' : Will put the packet drop mode into 50% loss mode and use a controller designed for 50% loss.
-'''mot50''' : This macro over-rides all other macros. If this is turned on the wheels will not run and the propellers will be run at 50% command. This is used for measuring the effective battery voltage seen by the ESCs. This is always run after a test.
-'''RADAlqi''' : This macro will cause the system to use an LQI controller on the whole system. The linear velocity states are calculated with no filter and the angular velocity states are calculated with filters.
-'''RADAlqi_est''' : This macro will cause the system to use an LQI controller on the whole system. A traditional estimator is used to estimate the states.
-'''rada_lqg''' : This macro will cause the entire system to be controlled by an LQG controller/estimator system.
-'''rada_split_lqg''' : This macro will cause the pendulum and ground robot to be controlled by their own LQG systems.
-'''rada_split_lqg_ol''' : This macro will cause the pendulum to be controlled by an LQG controller, the yaw of the ground robot to be controlled by a PID controller, and the ground robot linear velocities to be controlled with open-loop commands.
-'''yaw_off''' : This macro will cause the yaw control to be disabled on some controllers.
*'''accR''' : This macro will cause the PID linear velocity controllers to be given ramps to accelerate from one velocity to another instead of steps.
-'''posRamp''' : This macro will cause the linear velocities of RADA to be controlled by position PIDs with ramp reference instead of velocity commands.
-If no controller selection is made all controllers revert to PID controllers
All of these macros can be defined simply by uncommenting the corresponding define statement in main.cpp. The macros in the logger.cpp can be seen below:
-'''ssDrop''' : This macro puts the logger into packet drop controller mode and logs the correct values for the packet drop controllers.
-'''RADAlqi''' : This macro puts the logger into full system LQI controller logging mode.
-'''RADAlqi_est''' : This macro puts the logger into full system LQI controller plus estimator logging mode.
-'''rada_lqg''' : This puts the logger into full system LQG controller logging mode.
-'''rada_split_lqg''' : This macro causes the logger to log data about the subsystem LQG controllers.
-'''rada_split_lqg_ol''' : This cause the system to log data about the pendulum LQG system and the open-loop linear velocity commands.
-'''H2ctrl''' : This macro causes the logger to log data about the full system H2 controllers.
-If no logging mode is selected then the logger will default to logging PID data.
Because the system only calculates controllers for one set of controllers it is important to ensure that the logger is in the correct mode based off of what is defined in main.cpp. As of August 1st, 2016 the defines in main.cpp are not seen in logger.cpp.
Finally in a command prompt navigate to the driectroy: ''~/Desktop/rada_research_project/ErisResearchCode/CppProjects/MainProgram_PacketLoss''
Here just type: ''make''. The code will compile for your desired mode. For setting up a new development directory see [http://wikis.ece.iastate.edu/robotic-agriculture-data-acquisition/index.php/Setting_up_a_new_development_environment Setting up a new development environment] from the RADA Senior Design wiki.
[[Image:ComplingRADACode.png|800px]]
The complied executable code ends up in ''/home/shared/MainProject''. The ''/home/shared'' directory is setup as a network file share (NFS).
[[Image:ErisCompliedCode-config.png|800px]]
This service needs to be restarted when CO3050-11 is restarted. [http://wikis.ece.iastate.edu/robotic-agriculture-data-acquisition/index.php/Configuring_NFS_shares_for_the_robot Configure NFS shares for the robot] from the RADA Senior Design wiki. Be sure to use the new Linux install command in step six. Though I have found that even on a good strt the ''[ok]'' messages will still print.
=== Turning on RADA ===
Turning on Eris is fairly simple. Each system has its own battery. There is one for the wheels that plugs in at the front of Eris (opposite side of the switches), one for the electronics in the back of Eris (in between the switches), and one for the propellers that goes on top of Eris.
[[Image:ErisOnPhoto.jpg|800px]]
The wheel battery is normally 1600 mAh 2-cell Lipo but any 2-cell Lipo will work. The wheels are turned on by flipping the silver switch so the top points away from the system. The electronics normally use a 2600 mAh 2-cell Lipo. The electronics are turned on by flipping the green switch away from the system. It is important that you use EITHER the WIFI adapter OR hardwired Ethernet, because the VRPN may listen to the camera data broadcast over both connections which could cause problems. The propeller system is powered via a 2600 mAh 4-cell Lipo that connects to a power cable at the base of the pendulum. There is a switch to turn on the power to the propellers system. You will know it is on when the 1 on the switch is flush with the switch housing instead of sticking out. It takes about 30 seconds to a minute for Eris to boot up and start the networking connections. When the WIFI is plugged in, you will know it is ready when a blue light turns on, on the module.
=== Connecting to RADA ===
RADA is controlled through an SSH connection. in a commands prompt, not the one you compile the code from so that you can recompile for different setup without needing to close the connection. If you are using a WIFI connection use the command ''ssh root@192.168.0.53''. If you are connected to Eris through a LAN connection use the command ''ssh root@192.168.0.54''. If the connection goes though you should be prompted for a password.
The password is ''rootme''.
[[Image:Ssh2Eris.png|800px]]
It is important to close the SSH connection before turning off Eris because the terminal you are using will hang up if you don't. You can close the connection by using the command ''exit''.
[[Image:ClosingSSH.png|800px]]
== Testing RADA ==
Now that you are connected to Eris you can run tests. The testing is started by a few different methods.
=== Running the First Test After Power Up ===
For the first test after powering on Eris, a few additional steps need to be completed in order to test the system. The FPGA motor controller needs to be programmed and Eris needs to connect to the NFS server running on CO3050-11. This is accomplished by running ''1_co3050-11.sh'', this shell script will setup the NFS, and load the bit file into the FPGA configuration memory. Then it retrieves the executable file from the NFS server ''/mnt/nfs/MainProject'' and runs the executable. Once the user exits the executable, the log file produced is copied from the ''~/Logs/YYYY_MM_DD_Day'' directory on Eris to ''/home/shared/MainProject/Logs/YYYY_MM_DD_Day'' on CO3050-11. When the folder for the current Eris date doesn't exist it creates this directory in CO3050-11 and then removes the directory and log file from Eris. You may see a warning that when copying the log file Eris couldn't maintain the file permission settings. This is normal as Eris doesn't have the same access to the NSF server as it has to its own files. This date stamp uses the date on Eris, which is currently in June of 2008 as of August 2nd, 2016.
Before starting the test, it is best to have someone spotting the pendulum and holding it near vertical so that the pendulum doesn't have issues when entering a control mode.'''<span style="color:red"> Always ensure the pendulum is spotted by a second person when testing so you don't hurt yourself, others in the lab, or the RADA system.</span>''' Once the spotter is ready, run the shell script by using the command ''./1_co3050-11.sh'' in the terminal with the open SSH connection to Eris from the home, ''/root'', directory of Eris. When you run this script there will be a bunch of information printed out about the PIC bus and loading the bit file to configure the FPGA. You will know that RADA is ready for the test when it asks you to select a running mode. See the Testing Modes section below. This script can take a while to complete so beyond the first test after startup you don't need to run this script. See the Section about Running additional tests below.r
[[Image:StartingRADA initial.png|800px]]
=== Testing Modes ===
The RADA system has three testing modes: Robot Control Mode, Tuning Mode, and Box Step Mode. Additionally you can exit the execution at any time by pressing the ''Esc'' key. Once the terminal asks you to chose a mode you can use the following commands to enter the desired mode with a three second delay or exit the program. You can also use these commands to switch between the modes.
-''v'' : Enters the pendulum PID tuning mode, this will only really work when using PIDs to control the pendulum.
-''b'' : Enter Robot control mode, in this mode you can drive the robot around and the pendulum will try to stay vertical. This is the main mode used for testing the whole RADA system.
-''n'' : Enters box step mode, where the pendulum will change its desired pitch and roll angles every 20 seconds and move in a box shape.
-''Esc'' : By hitting the escape key the program will exit the program.
You will almost always want to run Robot Control Mode as the other modes are legacy modes from when we initially built and tested RADA and only works with the pendulum PID controllers. There are also a few utility commands that can be used in all modes.
-''2'' : Resets I composts of the Pitch/Roll PIDs and only the PIDs.
-''m'' : Adds a marker to the Log file incase odd things happen somewhere. This just increments a counter so if you use it look for changes in the marker value.
==== Robot Control Model ====
In Robot control mode you can control the motion of Eris. For PID control of Eris or 1D state feedback system the directional commands command Eris body velocity were for full system and Eris system state feedback controllers control the global velocity. All of these keys only need to be pressed not held down.
-''w'' : Moves Eris forward (+x) at some velocity depending on the controller.
-''s'' : Moves Eris in reverse (-x) at some velocity depending on the controller.
-''d'' : Moves Eris in right (+y) at some velocity depending on the controller.
-''a'' : Moves Eris in left (-y) at some velocity depending on the controller.
-''p'' : Stops the motion of Eris (Set all velocity set points to zero). I.e. if you hit ''w'' then hit ''s'' then Eris will be moving in reverse.
-''y'' : Moves Eris forward and to the right (+x/+y) simultaneously at some velocity depending on the controller.
-''t'' : Moves Eris forward and to the left (+x/-y) simultaneously at some velocity depending on the controller.
-''i'' : Moves Eris reverse and to the right (-x/+y) simultaneously at some velocity depending on the controller.
-''y'' : Moves Eris reverse and to the left (-x/-y) simultaneously at some velocity depending on the controller.
-''e'' : Rotate Eris clockwise (+yaw) at some angular rate. This only worked when RADA used the closed-loop FPGA control of the wheels. There is currently no controllers that use this command.
-''q'' : Rotate Eris counter-clockwise (-yaw) at some angular rate. This only worked when RADA used the closed-loop FPGA control of the wheels. There is currently no controllers that use this command.
-''<'' : Increment Eris' desired heading 45 degrees counter-clockwise (-yaw).
-''>'' : Increment Eris' desired heading 45 degrees clockwise (+yaw).
-''7'' : Increments the pitch set point (+pitch).
-''4'' : Decrements the pitch set point (-pitch).
-''8'' : Increments the roll set point (+roll).
-''5'' : Decrements the roll set point (-roll).
==== Tuning Mode ====
Tuning mode allows you to tune the PID controllers for both pitch and roll. The UI commands here are also available in Box Step Mode.
-''1'' : Tune the Pitch PID.
-''3'' : Tune the Roll PID.
-''7'' : Increase proportional gain of PID being tuned.
-''4'' : Decrease proportional gain of PID being tuned.
-''8'' : Increase integral gain of PID being tuned.
-''5'' : Decrease integral gain of PID being tuned.
-''9'' : Increase derivative gain of PID being tuned.
-''6'' : Decrease derivative gain of PID being tuned.
-''i'' : Increase set point of PID being tuned.
-''k'' : Decrease set point of PID being tuned.
-''o'' : Increase integral windup term of PID being tuned. (Not used)
-''l'' : Decrease integral windup term of PID being tuned. (Not used)
==== Box Step Mode ====
Box set mode will automatically change the set points of the pendulum every 20 seconds. The case statement for this mode can be changed for 1D and 2D step modes. This mode allows the user to use he same commands as Tuning Mode.
=== Running additional Tests ===
Once you have run one test with Eris on it is unnecessary to configure the FPGA or connect to the NFS server again. This is what took much of the time in the initial setup. This is what the script ''3_stat_eris.sh'' was developed for. It does everything that ''1_co3050-11.sh'' does but without reprogramming the FPGA or reconnecting to the NFS server. As a result it is ready to test much quicker.
Before starting the test it is best to have someone spotting the pendulum a holding it near vertical so that the pendulum doesn't have issues when entering a control mode.'''<span style="color:red"> Always run ensure the pendulum is spotted by a second person when testing so you don't hurt yourself, others in the lab, or the RADA system.</span>''' Once you spotter is ready run the shell scrip by= using the command ''./3_start_eris.sh'' in the terminal with the open SSH connection to Eris from the home, ''/root'', directory of Eris.
[[Image:StartingRADA2nd.png|800px]]
=== Locating and retrieving log files ===
If you are only demoing the system there is no need to go beyond this point. Once you are done with a test that you want to compare to the model you should retrieve the log file right away so you don't mix it up with other test. On CO3050-11 go to the dircetory ''/home/shared/MainProject/Logs'' using the file browser (you can do this in a terminal but it is easier from the file explorer). Once there, look for the folder that has been modified most recently as Eris date is normally out of sync with its date and time. Then look for the newest log file. Log files are named like ''log(hh.mm.ss).txt'' (ex. log(13.04.51).txt). This naming convention works well to ensure that no log file is over written but it isn't useful of describing what the test was of or for. Copy this log to the Desktop or to a USB drive and rename it. A good method is to name the file something like ''RADA_ctrl_otherNote#.txt'', where Describes what system you tested (ex. RADA, RADA1D, PEN1D, PEN2D), what typ of controller was used, other notes and then a number if this is a repeat of another test. This is much more useful when looking back at these logs later on. Before transferring the log file for processing you should record the wheel and propeller battery voltages in the header of the log file. The log file format is both human readable and can be parsed by MATALB. It was designed by the first RADA Senior Design Team and more information about the log files can be found [http://wikis.ece.iastate.edu/robotic-agriculture-data-acquisition/index.php/Data_Analysis_Tool here.] See he section below on measuring battery voltage below in order to get the best measurements for simulation of RADA.
=== Measuring battery voltages ===
The last thing that you need to do before simulating an experiment of the RADA platform is record the battery voltages for both the wheels and propellers. The wheel battery can be measured unloaded as there isn't large line losses between the battery and the H-bridges. The propeller battery voltage needs to be measured under load because the power cord running up the pendulum has significant line losses at the currents the propellers draw when in use. The battery voltages can be recorded in the log file for the test. Open the log file for the test you just completed (Use KWrite for Linux machines or Notepad++ for Windows machines). The first few lines of the log is the headder. It should look like this:
#Constants pitch_P pitch_I pitch_D
#PIDValues 48000 18000 21000
#Constants roll_P roll_I roll_D
#PIDValues 48000 18000 21000
#Battery Vquad Vwheels
#Voltage
Follow the procedure for measuring the voltage of each battery and then record the voltage under the corresponding battery. Then save the log file and close out of your text editor and the test will be ready for processing. Recoding the battery voltages in this way makes it much easier to find if you need the value latter. The final log file header should look like this once you are done
#Constants pitch_P pitch_I pitch_D
#PIDValues 48000 18000 21000
#Constants roll_P roll_I roll_D
#PIDValues 48000 18000 21000
#Battery Vquad Vwheels
#Voltage 14.44 8.257
==== Wheel Battery ====
1. After test disconnect wheel battery from the system.
2. Measure voltage of battery using multimeter.
[[Image:MeasureVwheel.jpg|800px]]
You can use the plug used for charging the 2-cell Lipos but make sure to connect the plug to the multimeter before connecting the battery and disconnect the battery before disconnecting the plug from the mulitmeter. It is generally the best practice to give the multimeter a few minutes to allow for the voltage measurement to stabilize as the battery measurement tends to be a little low right after the test. The multimeter will report data out to four decimal places it is best just to round to three decimal places for the wheel voltage.
==== Quad Battery ====
1. Setup code to run all four propellers at 50% throttle, uncomment the definition of ''mot50'' in main.cpp and compile the project.
2. Power off propellers by turning off the switch to the ESCs.
3. Connect multimeter to measure the voltage across one of the ESCs. This is done by using the power splitter cord.
-Connect one of the female XT60 connectors on the splitter to a male XT60 connector to banana connector cable.
-The banana connector connect to the hand held multimeter. The multimeter should be set to the 20VDC measurement setting.
-Next unplug one the ESCs' power connection.
-reconnect the ESC to power through the two remain connectors on the spliter cable.
4. Power on the propellers.
5. Run the system at 50% throttle and measure the steady-state voltage during the test. The battery will slow the voltage decay significantly, meaning it will keep the same measurement for a few seconds.
6. Stop the test and record the voltage in the log file. Make sure to disconnect the batter before removing the splitter cable.
{| class="wikitable" style="text-align:center"
|-
| [[Image:PowerSplitter.jpg|200px]]
| [[Image:QuadMultiCon.jpg |200px]]
| [[Image:QuadMultiSet.JPG |200px]]
| [[Image:QuadMeasESCcon.JPG|200px]]
|-
| Splitter cord.
| Connect splitter to multimeter.
| Settings for multimeter.
| Connecting ESC through splitter.
|}
The testing setup should look like the image below:
[[Image:QuadBattMeas.jpg|800px]]
== Post processing and Simulation ==
Simulating a test of RADA starts with processing and storing the data. Then all of the parameters of the model are loaded in the MATLAB Workspace. Finally the Simulink file used for the simulation is opened and the length of the simulation is set to match the length of the actual test. The simulation is run and the simulation output is stored. Finally the data should be plotted and compared.
=== Using the MATLAB data parsing tool ===
In depth discussion of how to use the log file parsing tool is described [http://wikis.ece.iastate.edu/robotic-agriculture-data-acquisition/index.php/Data_Analysis_Tool here.] I suggest using the version of the tool in the rada_resarch_project git repository Paul Uhing used for his Master's research. It con be found on CO3050-11 under the ucart account in the directory ''~/rada_research_project/DataAnalysiTool_omnicoor/Tool''. Simply open MATLAB and set the working directory to this file path. In the MATLAB Command Prompt run ''DataAnalysis''. A popup window should open up. Select the log file you want to process and wait for the tool to finish processing the file. Once this is complete there should be four structures in the MATLAB workspace.
-'''main''' : This contains all of the data extracted from the log file and the processing parameters used. main.expData contains two time structures: Time is used for the pendulum data and Eris_time is used for the ground vehicle data.
-'''X_ref''' : This contains the reference vector in m/s for x velocity that is feed into Simulink. This expedites the simulation setup process, this used to be done by hand.
-'''Y_ref''' : This contains the reference vector in m/s for y velocity that is feed into Simulink. This expedites the simulation setup process, this used to be done by hand.
-'''Yaw_ref''' : This contains the reference vector in radians for yaw that is feed into Simulink. This expedites the simulation setup process, this used to be done by hand. This one is new incase people start testing the system with heading changes but is not used in the current setup.
The first thing you should do is rename the main structure to the name you used for the log file. This is helpful for comparing multiple tests. Next you will want to crate two new variable ''Vquad_test'' an Vw_test''. In the MATLAB Command Prompt set the measured propeller voltage from the log file to ''Vquad_test'' and set the measured the wheel voltage to ''Vw_test'' as this will be used by the simulation. Finally if you did an open-loop test of the wheels create the variable ''Uol'' and set it to the open-loop wheel command used. Save all of these variables from the MATLAB workspace to a ''.mat'' file of the same name as log file you extracted the data from and save it in the same directory as your RADA Simulink files. As of August 2nd, 2016 this directory is ''~/rada_research_project/MATLAB/RADA.''
=== Setting up the MATLAB workspace for simulation ===
Change your MATLAB directory to this directory. Then run the simulation setup files. Currently you just need to run ''modelParams_smallWheels_RADA'' in the MATLAB Command Prompt. Next open the Simulink file with that contains the model of RADA controlled by the controller you tested.
-'''RADA_psiCtrl_v2_lqi_est.slx''' contains LQI, LQI+estimation, and LQG controller simulations.
-'''RADA_psiCtrl_v2.slx''' contains the PID controlled system.
-'''RADA_psiCtrl_v2_LQGsep.slx''' contains the subsystem LQG controlled system.
-'''RADA_psiCtrl_v2_LQGsep_ol.slx''' contains the simulation of the pendulum system controlled by an LQG and Eris controlled with open-loop commands.
Note all of the current (August 2nd, 2016) ''.slx'' files were created in MATLAB 2014b and will only work in MATLAB 2014B or newer. Then in the MATLAB Command Prompt type ''X_ref.time(end)'' exactly, don't add a semicolon, and hit enter. MATLAB will print the time of the last command in the X_ref structure. Set the en time of the simulation to this value and save your Simulink file.
=== Running simulations and storing results ===
Before running the simulation make sure that the simuation is using the ''ode23t'' differential equations solver. This system is a moderately stiff system of differential and the ''ode45'' solver doesn't do well with these types of systems. When using ''ode23t'' is should only take a few minutes to run a 100+ second simulation while doing the same test using ''ode45'' could take 8 hours. While this slow it is also bad for your hard drive as the simulation has to page between RAM and your computers hard drive a lot.
Once this check is done run the simulation. While it is running check what the output structures variables are named for for your RADA test system. Once the simulation is done go to your MATLAB Workspace and select all 15 outputs for your simulation or your sub-simulation if you used '''RADA_psiCtrl_v2_lqi_est.slx'''. Save these 15 output structures to a ''.mat'' file named as the log file with _sim appended to the end of the name.
The 15 outputs are structures containing a time vector and then the data from the simulation sampled at 100 Hz and the units of this data are the SI units (ex: radians, m/s). There is one output structure for x velocity, y velocity, x body velocity, y body velocity, theta (pitch), phi (roll), psi (yaw), and one per actuator command (ex: the command sent to a wheel). Now you have all the data you can plot it.
=== Plotting results ===
If you look at the ''DataSets'' folder below ''~/rada_research_project/MATLAB/RADA'' directory there are plenty of examples of how Paul Uhing compared simulation to test data. Generally you should grate a ''.m'' file with the same name as the log file this data was extracted from with _plot appended to the name.
Generally you can just copy an for RADA_LQG_compPID_plot.m RADA_PID_compLQG_plot.m, RADA_LQG_sep_plot.m, or RADA_LQG_sep_ol_plot.m files and rename the structures for your test.
These files create four figures. Figure 1 plots compares the x velocity data in the first sub figure and compares pitch (theta) data in the second sub figure. Figure 2 does the same thing as Figure 1 but with y velocity and roll data. Figure 3 looks at the yaw data. Finally, Figure 4 looks at the sample period between UAV and ERIS packets from the camera system just to check for periods of time with large packet drops.
You can follow a similar pattern to compare motor commands. Just make sure that you compare Quad Motor 2 from the test data with Quad Motor 4 from simulation and vise versa because propellers 2 and 4 were switch in Eris's software compared to the Model.
That is all you need to know for testing RADA against the model.
74052511bc9a81e54398dec64f9827e65d213aa4
337
333
2016-09-21T23:29:26Z
Jonessk
7
/* Setting up the Camera System */
wikitext
text/x-wiki
This page will take you though setting up and testing RADA, retrieving the log file and other necessary data to run a simulation of that test and processing the data in MATLAB. Then actually running the simulation of RADA in Simulink. The initial setup and how to test the system can also be applied to demoing RADA.
== Setting Up a RADA Test ==
Testing RADA is not overly difficult once you get the hang of the steps to setup RADA. The following steps may seem like a long process to go from starting the testing process to having completed simulation and plotting of the test results but this whole test procedure (with the exception of battery charging) can be completed in about 15-20 minutes. These steps are meant to be as detailed as possible in order to help new users of RADA get up and running as quickly as possible.
'''<span style="color:red">NOTE: Always run RADA with at least 2 people!</span>''' The pendulum arm can crash into the ground if the network starts to drop packets and one person cannot give commands to RADA and spot the pendulum. This is a safety issue for both you and the RADA platform.
=== Charging Batteries ===
The lab currently uses mostly Hyperion batteries. We charge our batteries with a Hyperion EOS 1420i Net3 battery charger. For some general information about how to use this charger see [https://www.youtube.com/watch?v=-ox3EpzvsJ8 this video.]. In the lab we power this charger using the old Kepco Power supply because it is the only power supply that can supply enough current. Make sure that the power supply is set to an output voltage between 10.5V-29V.
{| class="wikitable" style="text-align:center"
|-
| [[Image:ChargerPowerSupplyOff.JPG|400px]]
| [[Image:ChargerPowerSuplyOn.JPG|400px]]
|-
| Kepco Power Supply off.
| Kepco Power Supply on with correct voltage supply range.
|}
The YouTube video link above should explain how to use the charger. RADA currently uses three different Lithium polymer (Lipo) batteries: 1600 mAh 2-cell Lipo for the wheels, 2600 mAh 2-cell Lipo for the electronics of Eris, and a 2600 mAh 4-cell Lipo for the propellers. The 1600 mAh 2-cell Lipo can be charged using memory slot 2 of the charger. The 2600 mAh 2-cell Lipos can be charged using memory slot 3 for fast charging and memory slot 4 for slower charging (use this if the battery voltage drops really low for 10-20 minutes then switch to fast charging). The 2600 mAh 4-cell Lipo can be charged using memory slot 8. The 1600 mAh 2-cell and 2600 mAh 4-cell generally charge in 10-20 minutes apiece while the 2600 mAh 2-cell generally take up to 70 minutes to charge fully.
=== Setting up the Camera System ===
The camera system is run on the windows computer CO3050-07. You can log into this computer using a local microcart username and password (not posted here for security reasons, but any one who works in the lab should know it). Once logged in, look for Tracking Tools in the start menu or look for the shortcut shown below:
[[Image:TrackingTools_shortcut.PNG|thumb|center|Tracking Tools shortcut]]
Once the program opens the screen should look something like this:
[[Image:NewTrackingTools.PNG|800px]]
In the Tracking Tools Quick Start pop up menu select Open Existing Project and then navigate to ''D:\Optitrack_Configuration'' (It should open to this directory by default) and select the most recent Tracking Tools project. It should have the naming scheme ''TrackingToolsProject YYYY-MM-DD timeStamp.ttp''. This is normally the most recently edited file when sorting by date modified. The most recent one as of August 1st, 2016 is ''TrackingToolsProject 2015-09-23 2.30pm.ttp''.
[[Image:OpeningProject.PNG|800px]]
You should notice that the cameras shown in the main project screen arrange themselves like the camera system configuration once the project has been opened. Now the constellations need to be loaded. This can be done by going to ''File->Open'' and another popup window will open. Navigate back to ''D:\Optitrack_Configuration'' (It should open to this directory by default) and select the most recently dated set of RADA trackables. They have the naming scheme ''RADA_entireSystem_M_D_YYYY.tra''. The most recent one as of August 1st, 2016 is ''RADA_entireSystem_7_8_2016.tra''.
[[Image:Opening_trackables.PNG|800px]]
Once the project and trackables are open, the cameras should appear in their constellation (square) and there should be two constellations under ''Project Explorer->Trackables''. One named UAV for the pendulum and one named ERIS for the ground vehicle. In order to get additional information about each constellation, left click on the the name of the desired trackable.
[[Image:SelectingUAV.PNG|800px]]
Once a trackable is selected more information about it is available in the ''Trackables'' Tab on the right side of the screen. For the current position and orientation look at the ''Real-Time Info'' sub-tab. This gives the orientation in the wrong order for how we currently use the Euler angles. When two or three of the angles are near zero you can switch yaw and pitch to get roughly the correct orientation.
[[Image:Uav_realTimeInfo.PNG|800px]]
Now we need to check to make sure the system is zeroed.
#Hold RADA so that the front of the ground robot (ERIS is facing the wall with the white boards (east)). The front side of Eris is labeled. If it isn't, the front is the side opposite the switches and the side with the trackable constellation on it.
#Make sure that the motor with the red motor mount is also facing the wall with the white boards.
#Make sure the quad system is aligned along Eris Axis by standing behind the system. If the system is aligned, you should be able to block the mounting bolts of the front propeller motor with the pole while facing the east wall.
#While holding the pendulum approximately vertical, see if the camera system reads zeros for the pendulum (UAV) pitch and roll (yaw and roll in ''Real-Time Info''). If yaw is off by a few degrees that is fine.
#Compare the yaw of the UAV to that of ERIS (Remember this is pitch in ''Real-Time Info''). If they are both near zero and within a few degrees and the pendulum's pitch/roll were also near zero then you are ready to use the camera system. Otherwise, go to the next step.
#You need to zero the pendulum.
##Align ERIS so it is near zero yaw first (eye ball it).
##Get a level and a friend. Have your friend use a level to ensure that the pendulum is level in both directions and hold it there.
##With the UAV constellation selected go to the ''Orientation'' tab (next to ''Real-Time Info'' tab) and click on ''Reset To Current Orientation button''
##Now your friend can set the pendulum down and you can zero ERIS the same way.
#Save the new trackable orientation by going to ''File->Save Trackables...'' and save a file using the same naming conventions as the trackable file you opened earlier. Use the current data so you don't have to re-zero the system the next time you test.
[[Image:Uav_ResetOrientation.PNG|800px]]
=== Building Software ===
The development environment for running RADA is hosted on CO3050-11, a Linux Red Hat environment. This computer has a local ucart user name that you should use (the password isn't put here for security reasons). First, ensure that the RADA software is setup correctly for the test you want to run. To do this, you will need to open the main.cpp and logger.cpp files and make sure all of the compile time macros you want are defined correctly. All of the c++ files you should need to edit are in the directory ''~/Desktop/rada_research_project/ErisResearchCode/CppProjects/MainProgram_PacketLoss/src/Korebot'' Below are compiler macro options for main.cpp:
-'''H2ctrl''' : This will cause the system to enter H2 controller mode where the whole RADA system is controlled by an H2 controller.
-'''ssTracking''' : H2ctrl must also be defined for this macro to do anything. This macro will has the system to be controlled by a tracking H2 controller.
-'''ssMotors''' : H2ctrl must also be defined for this macro to do anything. This macro will has the system to be controlled by an H2 contorller that contains propeller states. This also causes the system to "Dance."
-'''ssDrop''' : Cause the system to go into packet drop controller mode. This mode allows controllers designed for lossy networks to be tested. Based off of other definitions how lossy the network is can be simulated. If nothing else is defined this controller becomes basically a H2 controller.
-'''drop10''' : Will put the packet drop mode into 10% loss mode and use a controller designed for 10% loss.
-'''drop30''' : Will put the packet drop mode into 30% loss mode and use a controller designed for 30% loss.
-'''drop50''' : Will put the packet drop mode into 50% loss mode and use a controller designed for 50% loss.
-'''mot50''' : This macro over-rides all other macros. If this is turned on the wheels will not run and the propellers will be run at 50% command. This is used for measuring the effective battery voltage seen by the ESCs. This is always run after a test.
-'''RADAlqi''' : This macro will cause the system to use an LQI controller on the whole system. The linear velocity states are calculated with no filter and the angular velocity states are calculated with filters.
-'''RADAlqi_est''' : This macro will cause the system to use an LQI controller on the whole system. A traditional estimator is used to estimate the states.
-'''rada_lqg''' : This macro will cause the entire system to be controlled by an LQG controller/estimator system.
-'''rada_split_lqg''' : This macro will cause the pendulum and ground robot to be controlled by their own LQG systems.
-'''rada_split_lqg_ol''' : This macro will cause the pendulum to be controlled by an LQG controller, the yaw of the ground robot to be controlled by a PID controller, and the ground robot linear velocities to be controlled with open-loop commands.
-'''yaw_off''' : This macro will cause the yaw control to be disabled on some controllers.
*'''accR''' : This macro will cause the PID linear velocity controllers to be given ramps to accelerate from one velocity to another instead of steps.
-'''posRamp''' : This macro will cause the linear velocities of RADA to be controlled by position PIDs with ramp reference instead of velocity commands.
-If no controller selection is made all controllers revert to PID controllers
All of these macros can be defined simply by uncommenting the corresponding define statement in main.cpp. The macros in the logger.cpp can be seen below:
-'''ssDrop''' : This macro puts the logger into packet drop controller mode and logs the correct values for the packet drop controllers.
-'''RADAlqi''' : This macro puts the logger into full system LQI controller logging mode.
-'''RADAlqi_est''' : This macro puts the logger into full system LQI controller plus estimator logging mode.
-'''rada_lqg''' : This puts the logger into full system LQG controller logging mode.
-'''rada_split_lqg''' : This macro causes the logger to log data about the subsystem LQG controllers.
-'''rada_split_lqg_ol''' : This cause the system to log data about the pendulum LQG system and the open-loop linear velocity commands.
-'''H2ctrl''' : This macro causes the logger to log data about the full system H2 controllers.
-If no logging mode is selected then the logger will default to logging PID data.
Because the system only calculates controllers for one set of controllers it is important to ensure that the logger is in the correct mode based off of what is defined in main.cpp. As of August 1st, 2016 the defines in main.cpp are not seen in logger.cpp.
Finally in a command prompt navigate to the driectroy: ''~/Desktop/rada_research_project/ErisResearchCode/CppProjects/MainProgram_PacketLoss''
Here just type: ''make''. The code will compile for your desired mode. For setting up a new development directory see [http://wikis.ece.iastate.edu/robotic-agriculture-data-acquisition/index.php/Setting_up_a_new_development_environment Setting up a new development environment] from the RADA Senior Design wiki.
[[Image:ComplingRADACode.png|800px]]
The complied executable code ends up in ''/home/shared/MainProject''. The ''/home/shared'' directory is setup as a network file share (NFS).
[[Image:ErisCompliedCode-config.png|800px]]
This service needs to be restarted when CO3050-11 is restarted. [http://wikis.ece.iastate.edu/robotic-agriculture-data-acquisition/index.php/Configuring_NFS_shares_for_the_robot Configure NFS shares for the robot] from the RADA Senior Design wiki. Be sure to use the new Linux install command in step six. Though I have found that even on a good strt the ''[ok]'' messages will still print.
=== Turning on RADA ===
Turning on Eris is fairly simple. Each system has its own battery. There is one for the wheels that plugs in at the front of Eris (opposite side of the switches), one for the electronics in the back of Eris (in between the switches), and one for the propellers that goes on top of Eris.
[[Image:ErisOnPhoto.jpg|800px]]
The wheel battery is normally 1600 mAh 2-cell Lipo but any 2-cell Lipo will work. The wheels are turned on by flipping the silver switch so the top points away from the system. The electronics normally use a 2600 mAh 2-cell Lipo. The electronics are turned on by flipping the green switch away from the system. It is important that you use EITHER the WIFI adapter OR hardwired Ethernet, because the VRPN may listen to the camera data broadcast over both connections which could cause problems. The propeller system is powered via a 2600 mAh 4-cell Lipo that connects to a power cable at the base of the pendulum. There is a switch to turn on the power to the propellers system. You will know it is on when the 1 on the switch is flush with the switch housing instead of sticking out. It takes about 30 seconds to a minute for Eris to boot up and start the networking connections. When the WIFI is plugged in, you will know it is ready when a blue light turns on, on the module.
=== Connecting to RADA ===
RADA is controlled through an SSH connection. in a commands prompt, not the one you compile the code from so that you can recompile for different setup without needing to close the connection. If you are using a WIFI connection use the command ''ssh root@192.168.0.53''. If you are connected to Eris through a LAN connection use the command ''ssh root@192.168.0.54''. If the connection goes though you should be prompted for a password.
The password is ''rootme''.
[[Image:Ssh2Eris.png|800px]]
It is important to close the SSH connection before turning off Eris because the terminal you are using will hang up if you don't. You can close the connection by using the command ''exit''.
[[Image:ClosingSSH.png|800px]]
== Testing RADA ==
Now that you are connected to Eris you can run tests. The testing is started by a few different methods.
=== Running the First Test After Power Up ===
For the first test after powering on Eris, a few additional steps need to be completed in order to test the system. The FPGA motor controller needs to be programmed and Eris needs to connect to the NFS server running on CO3050-11. This is accomplished by running ''1_co3050-11.sh'', this shell script will setup the NFS, and load the bit file into the FPGA configuration memory. Then it retrieves the executable file from the NFS server ''/mnt/nfs/MainProject'' and runs the executable. Once the user exits the executable, the log file produced is copied from the ''~/Logs/YYYY_MM_DD_Day'' directory on Eris to ''/home/shared/MainProject/Logs/YYYY_MM_DD_Day'' on CO3050-11. When the folder for the current Eris date doesn't exist it creates this directory in CO3050-11 and then removes the directory and log file from Eris. You may see a warning that when copying the log file Eris couldn't maintain the file permission settings. This is normal as Eris doesn't have the same access to the NSF server as it has to its own files. This date stamp uses the date on Eris, which is currently in June of 2008 as of August 2nd, 2016.
Before starting the test, it is best to have someone spotting the pendulum and holding it near vertical so that the pendulum doesn't have issues when entering a control mode.'''<span style="color:red"> Always ensure the pendulum is spotted by a second person when testing so you don't hurt yourself, others in the lab, or the RADA system.</span>''' Once the spotter is ready, run the shell script by using the command ''./1_co3050-11.sh'' in the terminal with the open SSH connection to Eris from the home, ''/root'', directory of Eris. When you run this script there will be a bunch of information printed out about the PIC bus and loading the bit file to configure the FPGA. You will know that RADA is ready for the test when it asks you to select a running mode. See the Testing Modes section below. This script can take a while to complete so beyond the first test after startup you don't need to run this script. See the Section about Running additional tests below.r
[[Image:StartingRADA initial.png|800px]]
=== Testing Modes ===
The RADA system has three testing modes: Robot Control Mode, Tuning Mode, and Box Step Mode. Additionally you can exit the execution at any time by pressing the ''Esc'' key. Once the terminal asks you to chose a mode you can use the following commands to enter the desired mode with a three second delay or exit the program. You can also use these commands to switch between the modes.
-''v'' : Enters the pendulum PID tuning mode, this will only really work when using PIDs to control the pendulum.
-''b'' : Enter Robot control mode, in this mode you can drive the robot around and the pendulum will try to stay vertical. This is the main mode used for testing the whole RADA system.
-''n'' : Enters box step mode, where the pendulum will change its desired pitch and roll angles every 20 seconds and move in a box shape.
-''Esc'' : By hitting the escape key the program will exit the program.
You will almost always want to run Robot Control Mode as the other modes are legacy modes from when we initially built and tested RADA and only works with the pendulum PID controllers. There are also a few utility commands that can be used in all modes.
-''2'' : Resets I composts of the Pitch/Roll PIDs and only the PIDs.
-''m'' : Adds a marker to the Log file incase odd things happen somewhere. This just increments a counter so if you use it look for changes in the marker value.
==== Robot Control Model ====
In Robot control mode you can control the motion of Eris. For PID control of Eris or 1D state feedback system the directional commands command Eris body velocity were for full system and Eris system state feedback controllers control the global velocity. All of these keys only need to be pressed not held down.
-''w'' : Moves Eris forward (+x) at some velocity depending on the controller.
-''s'' : Moves Eris in reverse (-x) at some velocity depending on the controller.
-''d'' : Moves Eris in right (+y) at some velocity depending on the controller.
-''a'' : Moves Eris in left (-y) at some velocity depending on the controller.
-''p'' : Stops the motion of Eris (Set all velocity set points to zero). I.e. if you hit ''w'' then hit ''s'' then Eris will be moving in reverse.
-''y'' : Moves Eris forward and to the right (+x/+y) simultaneously at some velocity depending on the controller.
-''t'' : Moves Eris forward and to the left (+x/-y) simultaneously at some velocity depending on the controller.
-''i'' : Moves Eris reverse and to the right (-x/+y) simultaneously at some velocity depending on the controller.
-''y'' : Moves Eris reverse and to the left (-x/-y) simultaneously at some velocity depending on the controller.
-''e'' : Rotate Eris clockwise (+yaw) at some angular rate. This only worked when RADA used the closed-loop FPGA control of the wheels. There is currently no controllers that use this command.
-''q'' : Rotate Eris counter-clockwise (-yaw) at some angular rate. This only worked when RADA used the closed-loop FPGA control of the wheels. There is currently no controllers that use this command.
-''<'' : Increment Eris' desired heading 45 degrees counter-clockwise (-yaw).
-''>'' : Increment Eris' desired heading 45 degrees clockwise (+yaw).
-''7'' : Increments the pitch set point (+pitch).
-''4'' : Decrements the pitch set point (-pitch).
-''8'' : Increments the roll set point (+roll).
-''5'' : Decrements the roll set point (-roll).
==== Tuning Mode ====
Tuning mode allows you to tune the PID controllers for both pitch and roll. The UI commands here are also available in Box Step Mode.
-''1'' : Tune the Pitch PID.
-''3'' : Tune the Roll PID.
-''7'' : Increase proportional gain of PID being tuned.
-''4'' : Decrease proportional gain of PID being tuned.
-''8'' : Increase integral gain of PID being tuned.
-''5'' : Decrease integral gain of PID being tuned.
-''9'' : Increase derivative gain of PID being tuned.
-''6'' : Decrease derivative gain of PID being tuned.
-''i'' : Increase set point of PID being tuned.
-''k'' : Decrease set point of PID being tuned.
-''o'' : Increase integral windup term of PID being tuned. (Not used)
-''l'' : Decrease integral windup term of PID being tuned. (Not used)
==== Box Step Mode ====
Box set mode will automatically change the set points of the pendulum every 20 seconds. The case statement for this mode can be changed for 1D and 2D step modes. This mode allows the user to use he same commands as Tuning Mode.
=== Running additional Tests ===
Once you have run one test with Eris on it is unnecessary to configure the FPGA or connect to the NFS server again. This is what took much of the time in the initial setup. This is what the script ''3_stat_eris.sh'' was developed for. It does everything that ''1_co3050-11.sh'' does but without reprogramming the FPGA or reconnecting to the NFS server. As a result it is ready to test much quicker.
Before starting the test it is best to have someone spotting the pendulum a holding it near vertical so that the pendulum doesn't have issues when entering a control mode.'''<span style="color:red"> Always run ensure the pendulum is spotted by a second person when testing so you don't hurt yourself, others in the lab, or the RADA system.</span>''' Once you spotter is ready run the shell scrip by= using the command ''./3_start_eris.sh'' in the terminal with the open SSH connection to Eris from the home, ''/root'', directory of Eris.
[[Image:StartingRADA2nd.png|800px]]
=== Locating and retrieving log files ===
If you are only demoing the system there is no need to go beyond this point. Once you are done with a test that you want to compare to the model you should retrieve the log file right away so you don't mix it up with other test. On CO3050-11 go to the dircetory ''/home/shared/MainProject/Logs'' using the file browser (you can do this in a terminal but it is easier from the file explorer). Once there, look for the folder that has been modified most recently as Eris date is normally out of sync with its date and time. Then look for the newest log file. Log files are named like ''log(hh.mm.ss).txt'' (ex. log(13.04.51).txt). This naming convention works well to ensure that no log file is over written but it isn't useful of describing what the test was of or for. Copy this log to the Desktop or to a USB drive and rename it. A good method is to name the file something like ''RADA_ctrl_otherNote#.txt'', where Describes what system you tested (ex. RADA, RADA1D, PEN1D, PEN2D), what typ of controller was used, other notes and then a number if this is a repeat of another test. This is much more useful when looking back at these logs later on. Before transferring the log file for processing you should record the wheel and propeller battery voltages in the header of the log file. The log file format is both human readable and can be parsed by MATALB. It was designed by the first RADA Senior Design Team and more information about the log files can be found [http://wikis.ece.iastate.edu/robotic-agriculture-data-acquisition/index.php/Data_Analysis_Tool here.] See he section below on measuring battery voltage below in order to get the best measurements for simulation of RADA.
=== Measuring battery voltages ===
The last thing that you need to do before simulating an experiment of the RADA platform is record the battery voltages for both the wheels and propellers. The wheel battery can be measured unloaded as there isn't large line losses between the battery and the H-bridges. The propeller battery voltage needs to be measured under load because the power cord running up the pendulum has significant line losses at the currents the propellers draw when in use. The battery voltages can be recorded in the log file for the test. Open the log file for the test you just completed (Use KWrite for Linux machines or Notepad++ for Windows machines). The first few lines of the log is the headder. It should look like this:
#Constants pitch_P pitch_I pitch_D
#PIDValues 48000 18000 21000
#Constants roll_P roll_I roll_D
#PIDValues 48000 18000 21000
#Battery Vquad Vwheels
#Voltage
Follow the procedure for measuring the voltage of each battery and then record the voltage under the corresponding battery. Then save the log file and close out of your text editor and the test will be ready for processing. Recoding the battery voltages in this way makes it much easier to find if you need the value latter. The final log file header should look like this once you are done
#Constants pitch_P pitch_I pitch_D
#PIDValues 48000 18000 21000
#Constants roll_P roll_I roll_D
#PIDValues 48000 18000 21000
#Battery Vquad Vwheels
#Voltage 14.44 8.257
==== Wheel Battery ====
1. After test disconnect wheel battery from the system.
2. Measure voltage of battery using multimeter.
[[Image:MeasureVwheel.jpg|800px]]
You can use the plug used for charging the 2-cell Lipos but make sure to connect the plug to the multimeter before connecting the battery and disconnect the battery before disconnecting the plug from the mulitmeter. It is generally the best practice to give the multimeter a few minutes to allow for the voltage measurement to stabilize as the battery measurement tends to be a little low right after the test. The multimeter will report data out to four decimal places it is best just to round to three decimal places for the wheel voltage.
==== Quad Battery ====
1. Setup code to run all four propellers at 50% throttle, uncomment the definition of ''mot50'' in main.cpp and compile the project.
2. Power off propellers by turning off the switch to the ESCs.
3. Connect multimeter to measure the voltage across one of the ESCs. This is done by using the power splitter cord.
-Connect one of the female XT60 connectors on the splitter to a male XT60 connector to banana connector cable.
-The banana connector connect to the hand held multimeter. The multimeter should be set to the 20VDC measurement setting.
-Next unplug one the ESCs' power connection.
-reconnect the ESC to power through the two remain connectors on the spliter cable.
4. Power on the propellers.
5. Run the system at 50% throttle and measure the steady-state voltage during the test. The battery will slow the voltage decay significantly, meaning it will keep the same measurement for a few seconds.
6. Stop the test and record the voltage in the log file. Make sure to disconnect the batter before removing the splitter cable.
{| class="wikitable" style="text-align:center"
|-
| [[Image:PowerSplitter.jpg|200px]]
| [[Image:QuadMultiCon.jpg |200px]]
| [[Image:QuadMultiSet.JPG |200px]]
| [[Image:QuadMeasESCcon.JPG|200px]]
|-
| Splitter cord.
| Connect splitter to multimeter.
| Settings for multimeter.
| Connecting ESC through splitter.
|}
The testing setup should look like the image below:
[[Image:QuadBattMeas.jpg|800px]]
== Post processing and Simulation ==
Simulating a test of RADA starts with processing and storing the data. Then all of the parameters of the model are loaded in the MATLAB Workspace. Finally the Simulink file used for the simulation is opened and the length of the simulation is set to match the length of the actual test. The simulation is run and the simulation output is stored. Finally the data should be plotted and compared.
=== Using the MATLAB data parsing tool ===
In depth discussion of how to use the log file parsing tool is described [http://wikis.ece.iastate.edu/robotic-agriculture-data-acquisition/index.php/Data_Analysis_Tool here.] I suggest using the version of the tool in the rada_resarch_project git repository Paul Uhing used for his Master's research. It con be found on CO3050-11 under the ucart account in the directory ''~/rada_research_project/DataAnalysiTool_omnicoor/Tool''. Simply open MATLAB and set the working directory to this file path. In the MATLAB Command Prompt run ''DataAnalysis''. A popup window should open up. Select the log file you want to process and wait for the tool to finish processing the file. Once this is complete there should be four structures in the MATLAB workspace.
-'''main''' : This contains all of the data extracted from the log file and the processing parameters used. main.expData contains two time structures: Time is used for the pendulum data and Eris_time is used for the ground vehicle data.
-'''X_ref''' : This contains the reference vector in m/s for x velocity that is feed into Simulink. This expedites the simulation setup process, this used to be done by hand.
-'''Y_ref''' : This contains the reference vector in m/s for y velocity that is feed into Simulink. This expedites the simulation setup process, this used to be done by hand.
-'''Yaw_ref''' : This contains the reference vector in radians for yaw that is feed into Simulink. This expedites the simulation setup process, this used to be done by hand. This one is new incase people start testing the system with heading changes but is not used in the current setup.
The first thing you should do is rename the main structure to the name you used for the log file. This is helpful for comparing multiple tests. Next you will want to crate two new variable ''Vquad_test'' an Vw_test''. In the MATLAB Command Prompt set the measured propeller voltage from the log file to ''Vquad_test'' and set the measured the wheel voltage to ''Vw_test'' as this will be used by the simulation. Finally if you did an open-loop test of the wheels create the variable ''Uol'' and set it to the open-loop wheel command used. Save all of these variables from the MATLAB workspace to a ''.mat'' file of the same name as log file you extracted the data from and save it in the same directory as your RADA Simulink files. As of August 2nd, 2016 this directory is ''~/rada_research_project/MATLAB/RADA.''
=== Setting up the MATLAB workspace for simulation ===
Change your MATLAB directory to this directory. Then run the simulation setup files. Currently you just need to run ''modelParams_smallWheels_RADA'' in the MATLAB Command Prompt. Next open the Simulink file with that contains the model of RADA controlled by the controller you tested.
-'''RADA_psiCtrl_v2_lqi_est.slx''' contains LQI, LQI+estimation, and LQG controller simulations.
-'''RADA_psiCtrl_v2.slx''' contains the PID controlled system.
-'''RADA_psiCtrl_v2_LQGsep.slx''' contains the subsystem LQG controlled system.
-'''RADA_psiCtrl_v2_LQGsep_ol.slx''' contains the simulation of the pendulum system controlled by an LQG and Eris controlled with open-loop commands.
Note all of the current (August 2nd, 2016) ''.slx'' files were created in MATLAB 2014b and will only work in MATLAB 2014B or newer. Then in the MATLAB Command Prompt type ''X_ref.time(end)'' exactly, don't add a semicolon, and hit enter. MATLAB will print the time of the last command in the X_ref structure. Set the en time of the simulation to this value and save your Simulink file.
=== Running simulations and storing results ===
Before running the simulation make sure that the simuation is using the ''ode23t'' differential equations solver. This system is a moderately stiff system of differential and the ''ode45'' solver doesn't do well with these types of systems. When using ''ode23t'' is should only take a few minutes to run a 100+ second simulation while doing the same test using ''ode45'' could take 8 hours. While this slow it is also bad for your hard drive as the simulation has to page between RAM and your computers hard drive a lot.
Once this check is done run the simulation. While it is running check what the output structures variables are named for for your RADA test system. Once the simulation is done go to your MATLAB Workspace and select all 15 outputs for your simulation or your sub-simulation if you used '''RADA_psiCtrl_v2_lqi_est.slx'''. Save these 15 output structures to a ''.mat'' file named as the log file with _sim appended to the end of the name.
The 15 outputs are structures containing a time vector and then the data from the simulation sampled at 100 Hz and the units of this data are the SI units (ex: radians, m/s). There is one output structure for x velocity, y velocity, x body velocity, y body velocity, theta (pitch), phi (roll), psi (yaw), and one per actuator command (ex: the command sent to a wheel). Now you have all the data you can plot it.
=== Plotting results ===
If you look at the ''DataSets'' folder below ''~/rada_research_project/MATLAB/RADA'' directory there are plenty of examples of how Paul Uhing compared simulation to test data. Generally you should grate a ''.m'' file with the same name as the log file this data was extracted from with _plot appended to the name.
Generally you can just copy an for RADA_LQG_compPID_plot.m RADA_PID_compLQG_plot.m, RADA_LQG_sep_plot.m, or RADA_LQG_sep_ol_plot.m files and rename the structures for your test.
These files create four figures. Figure 1 plots compares the x velocity data in the first sub figure and compares pitch (theta) data in the second sub figure. Figure 2 does the same thing as Figure 1 but with y velocity and roll data. Figure 3 looks at the yaw data. Finally, Figure 4 looks at the sample period between UAV and ERIS packets from the camera system just to check for periods of time with large packet drops.
You can follow a similar pattern to compare motor commands. Just make sure that you compare Quad Motor 2 from the test data with Quad Motor 4 from simulation and vise versa because propellers 2 and 4 were switch in Eris's software compared to the Model.
That is all you need to know for testing RADA against the model.
e0c3b70e853d485b712343f2080c870d3dc77360
338
337
2016-09-21T23:31:22Z
Jonessk
7
/* Setting up the Camera System */
wikitext
text/x-wiki
This page will take you though setting up and testing RADA, retrieving the log file and other necessary data to run a simulation of that test and processing the data in MATLAB. Then actually running the simulation of RADA in Simulink. The initial setup and how to test the system can also be applied to demoing RADA.
== Setting Up a RADA Test ==
Testing RADA is not overly difficult once you get the hang of the steps to setup RADA. The following steps may seem like a long process to go from starting the testing process to having completed simulation and plotting of the test results but this whole test procedure (with the exception of battery charging) can be completed in about 15-20 minutes. These steps are meant to be as detailed as possible in order to help new users of RADA get up and running as quickly as possible.
'''<span style="color:red">NOTE: Always run RADA with at least 2 people!</span>''' The pendulum arm can crash into the ground if the network starts to drop packets and one person cannot give commands to RADA and spot the pendulum. This is a safety issue for both you and the RADA platform.
=== Charging Batteries ===
The lab currently uses mostly Hyperion batteries. We charge our batteries with a Hyperion EOS 1420i Net3 battery charger. For some general information about how to use this charger see [https://www.youtube.com/watch?v=-ox3EpzvsJ8 this video.]. In the lab we power this charger using the old Kepco Power supply because it is the only power supply that can supply enough current. Make sure that the power supply is set to an output voltage between 10.5V-29V.
{| class="wikitable" style="text-align:center"
|-
| [[Image:ChargerPowerSupplyOff.JPG|400px]]
| [[Image:ChargerPowerSuplyOn.JPG|400px]]
|-
| Kepco Power Supply off.
| Kepco Power Supply on with correct voltage supply range.
|}
The YouTube video link above should explain how to use the charger. RADA currently uses three different Lithium polymer (Lipo) batteries: 1600 mAh 2-cell Lipo for the wheels, 2600 mAh 2-cell Lipo for the electronics of Eris, and a 2600 mAh 4-cell Lipo for the propellers. The 1600 mAh 2-cell Lipo can be charged using memory slot 2 of the charger. The 2600 mAh 2-cell Lipos can be charged using memory slot 3 for fast charging and memory slot 4 for slower charging (use this if the battery voltage drops really low for 10-20 minutes then switch to fast charging). The 2600 mAh 4-cell Lipo can be charged using memory slot 8. The 1600 mAh 2-cell and 2600 mAh 4-cell generally charge in 10-20 minutes apiece while the 2600 mAh 2-cell generally take up to 70 minutes to charge fully.
=== Setting up the Camera System ===
The camera system is run on the windows computer CO3050-07. You can log into this computer using a local microcart username and password (not posted here for security reasons, but any one who works in the lab should know it). Once logged in, look for Tracking Tools in the start menu or look for the shortcut shown below:
[[Image:TrackingTools_shortcut.PNG|thumb|center|Tracking Tools shortcut]]
Once the program opens the screen should look something like this:
[[Image:NewTrackingTools.PNG|800px]]
In the Tracking Tools Quick Start pop up menu select Open Existing Project and then navigate to ''D:\Optitrack_Configuration'' (It should open to this directory by default) and select the most recent Tracking Tools project. It should have the naming scheme ''TrackingToolsProject YYYY-MM-DD timeStamp.ttp''. This is normally the most recently edited file when sorting by date modified. The most recent one as of August 1st, 2016 is ''TrackingToolsProject 2015-09-23 2.30pm.ttp''.
[[Image:OpeningProject.PNG|800px]]
You should notice that the cameras shown in the main project screen arrange themselves like the camera system configuration once the project has been opened. Now the constellations need to be loaded. This can be done by going to ''File->Open'' and another popup window will open. Navigate back to ''D:\Optitrack_Configuration'' (It should open to this directory by default) and select the most recently dated set of RADA trackables. They have the naming scheme ''RADA_entireSystem_M_D_YYYY.tra''. The most recent one as of August 1st, 2016 is ''RADA_entireSystem_7_8_2016.tra''.
[[Image:Opening_trackables.PNG|800px]]
Once the project and trackables are open, the cameras should appear in their constellation (square) and there should be two constellations under ''Project Explorer->Trackables''. One named UAV for the pendulum and one named ERIS for the ground vehicle. In order to get additional information about each constellation, left click on the the name of the desired trackable.
[[Image:SelectingUAV.PNG|800px]]
Once a trackable is selected more information about it is available in the ''Trackables'' Tab on the right side of the screen. For the current position and orientation look at the ''Real-Time Info'' sub-tab. This gives the orientation in the wrong order for how we currently use the Euler angles. When two or three of the angles are near zero you can switch yaw and pitch to get roughly the correct orientation.
[[Image:Uav_realTimeInfo.PNG|800px]]
Now we need to check to make sure the system is zeroed.
#Hold RADA so that the front of the ground robot (ERIS is facing the wall with the white boards (east)). The front side of Eris is labeled. If it isn't, the front is the side opposite the switches and the side with the trackable constellation on it.
#Make sure that the motor with the red motor mount is also facing the wall with the white boards.
#Make sure the quad system is aligned along Eris Axis by standing behind the system. If the system is aligned, you should be able to block the mounting bolts of the front propeller motor with the pole while facing the east wall.
#While holding the pendulum approximately vertical, see if the camera system reads zeros for the pendulum (UAV) pitch and roll (yaw and roll in ''Real-Time Info''). If yaw is off by a few degrees that is fine.
#Compare the yaw of the UAV to that of ERIS (Remember this is pitch in ''Real-Time Info''). If they are both near zero and within a few degrees and the pendulum's pitch/roll were also near zero then you are ready to use the camera system. Otherwise, go to the next step.
#You need to zero the pendulum.
##Align ERIS so it is near zero yaw first (eye ball it).
##Get a level and a friend. Have your friend use a level to ensure that the pendulum is level in both directions and hold it there.
##With the UAV constellation selected go to the ''Orientation'' tab (next to ''Real-Time Info'' tab) and click on ''Reset To Current Orientation'' button
##Now your friend can set the pendulum down and you can zero ERIS the same way.
#Save the new trackable orientation by going to ''File->Save Trackables...'' and save a file using the same naming conventions as the trackable file you opened earlier. Use the current data so you don't have to re-zero the system the next time you test.
[[Image:Uav_ResetOrientation.PNG|800px]]
=== Building Software ===
The development environment for running RADA is hosted on CO3050-11, a Linux Red Hat environment. This computer has a local ucart user name that you should use (the password isn't put here for security reasons). First, ensure that the RADA software is setup correctly for the test you want to run. To do this, you will need to open the main.cpp and logger.cpp files and make sure all of the compile time macros you want are defined correctly. All of the c++ files you should need to edit are in the directory ''~/Desktop/rada_research_project/ErisResearchCode/CppProjects/MainProgram_PacketLoss/src/Korebot'' Below are compiler macro options for main.cpp:
-'''H2ctrl''' : This will cause the system to enter H2 controller mode where the whole RADA system is controlled by an H2 controller.
-'''ssTracking''' : H2ctrl must also be defined for this macro to do anything. This macro will has the system to be controlled by a tracking H2 controller.
-'''ssMotors''' : H2ctrl must also be defined for this macro to do anything. This macro will has the system to be controlled by an H2 contorller that contains propeller states. This also causes the system to "Dance."
-'''ssDrop''' : Cause the system to go into packet drop controller mode. This mode allows controllers designed for lossy networks to be tested. Based off of other definitions how lossy the network is can be simulated. If nothing else is defined this controller becomes basically a H2 controller.
-'''drop10''' : Will put the packet drop mode into 10% loss mode and use a controller designed for 10% loss.
-'''drop30''' : Will put the packet drop mode into 30% loss mode and use a controller designed for 30% loss.
-'''drop50''' : Will put the packet drop mode into 50% loss mode and use a controller designed for 50% loss.
-'''mot50''' : This macro over-rides all other macros. If this is turned on the wheels will not run and the propellers will be run at 50% command. This is used for measuring the effective battery voltage seen by the ESCs. This is always run after a test.
-'''RADAlqi''' : This macro will cause the system to use an LQI controller on the whole system. The linear velocity states are calculated with no filter and the angular velocity states are calculated with filters.
-'''RADAlqi_est''' : This macro will cause the system to use an LQI controller on the whole system. A traditional estimator is used to estimate the states.
-'''rada_lqg''' : This macro will cause the entire system to be controlled by an LQG controller/estimator system.
-'''rada_split_lqg''' : This macro will cause the pendulum and ground robot to be controlled by their own LQG systems.
-'''rada_split_lqg_ol''' : This macro will cause the pendulum to be controlled by an LQG controller, the yaw of the ground robot to be controlled by a PID controller, and the ground robot linear velocities to be controlled with open-loop commands.
-'''yaw_off''' : This macro will cause the yaw control to be disabled on some controllers.
*'''accR''' : This macro will cause the PID linear velocity controllers to be given ramps to accelerate from one velocity to another instead of steps.
-'''posRamp''' : This macro will cause the linear velocities of RADA to be controlled by position PIDs with ramp reference instead of velocity commands.
-If no controller selection is made all controllers revert to PID controllers
All of these macros can be defined simply by uncommenting the corresponding define statement in main.cpp. The macros in the logger.cpp can be seen below:
-'''ssDrop''' : This macro puts the logger into packet drop controller mode and logs the correct values for the packet drop controllers.
-'''RADAlqi''' : This macro puts the logger into full system LQI controller logging mode.
-'''RADAlqi_est''' : This macro puts the logger into full system LQI controller plus estimator logging mode.
-'''rada_lqg''' : This puts the logger into full system LQG controller logging mode.
-'''rada_split_lqg''' : This macro causes the logger to log data about the subsystem LQG controllers.
-'''rada_split_lqg_ol''' : This cause the system to log data about the pendulum LQG system and the open-loop linear velocity commands.
-'''H2ctrl''' : This macro causes the logger to log data about the full system H2 controllers.
-If no logging mode is selected then the logger will default to logging PID data.
Because the system only calculates controllers for one set of controllers it is important to ensure that the logger is in the correct mode based off of what is defined in main.cpp. As of August 1st, 2016 the defines in main.cpp are not seen in logger.cpp.
Finally in a command prompt navigate to the driectroy: ''~/Desktop/rada_research_project/ErisResearchCode/CppProjects/MainProgram_PacketLoss''
Here just type: ''make''. The code will compile for your desired mode. For setting up a new development directory see [http://wikis.ece.iastate.edu/robotic-agriculture-data-acquisition/index.php/Setting_up_a_new_development_environment Setting up a new development environment] from the RADA Senior Design wiki.
[[Image:ComplingRADACode.png|800px]]
The complied executable code ends up in ''/home/shared/MainProject''. The ''/home/shared'' directory is setup as a network file share (NFS).
[[Image:ErisCompliedCode-config.png|800px]]
This service needs to be restarted when CO3050-11 is restarted. [http://wikis.ece.iastate.edu/robotic-agriculture-data-acquisition/index.php/Configuring_NFS_shares_for_the_robot Configure NFS shares for the robot] from the RADA Senior Design wiki. Be sure to use the new Linux install command in step six. Though I have found that even on a good strt the ''[ok]'' messages will still print.
=== Turning on RADA ===
Turning on Eris is fairly simple. Each system has its own battery. There is one for the wheels that plugs in at the front of Eris (opposite side of the switches), one for the electronics in the back of Eris (in between the switches), and one for the propellers that goes on top of Eris.
[[Image:ErisOnPhoto.jpg|800px]]
The wheel battery is normally 1600 mAh 2-cell Lipo but any 2-cell Lipo will work. The wheels are turned on by flipping the silver switch so the top points away from the system. The electronics normally use a 2600 mAh 2-cell Lipo. The electronics are turned on by flipping the green switch away from the system. It is important that you use EITHER the WIFI adapter OR hardwired Ethernet, because the VRPN may listen to the camera data broadcast over both connections which could cause problems. The propeller system is powered via a 2600 mAh 4-cell Lipo that connects to a power cable at the base of the pendulum. There is a switch to turn on the power to the propellers system. You will know it is on when the 1 on the switch is flush with the switch housing instead of sticking out. It takes about 30 seconds to a minute for Eris to boot up and start the networking connections. When the WIFI is plugged in, you will know it is ready when a blue light turns on, on the module.
=== Connecting to RADA ===
RADA is controlled through an SSH connection. in a commands prompt, not the one you compile the code from so that you can recompile for different setup without needing to close the connection. If you are using a WIFI connection use the command ''ssh root@192.168.0.53''. If you are connected to Eris through a LAN connection use the command ''ssh root@192.168.0.54''. If the connection goes though you should be prompted for a password.
The password is ''rootme''.
[[Image:Ssh2Eris.png|800px]]
It is important to close the SSH connection before turning off Eris because the terminal you are using will hang up if you don't. You can close the connection by using the command ''exit''.
[[Image:ClosingSSH.png|800px]]
== Testing RADA ==
Now that you are connected to Eris you can run tests. The testing is started by a few different methods.
=== Running the First Test After Power Up ===
For the first test after powering on Eris, a few additional steps need to be completed in order to test the system. The FPGA motor controller needs to be programmed and Eris needs to connect to the NFS server running on CO3050-11. This is accomplished by running ''1_co3050-11.sh'', this shell script will setup the NFS, and load the bit file into the FPGA configuration memory. Then it retrieves the executable file from the NFS server ''/mnt/nfs/MainProject'' and runs the executable. Once the user exits the executable, the log file produced is copied from the ''~/Logs/YYYY_MM_DD_Day'' directory on Eris to ''/home/shared/MainProject/Logs/YYYY_MM_DD_Day'' on CO3050-11. When the folder for the current Eris date doesn't exist it creates this directory in CO3050-11 and then removes the directory and log file from Eris. You may see a warning that when copying the log file Eris couldn't maintain the file permission settings. This is normal as Eris doesn't have the same access to the NSF server as it has to its own files. This date stamp uses the date on Eris, which is currently in June of 2008 as of August 2nd, 2016.
Before starting the test, it is best to have someone spotting the pendulum and holding it near vertical so that the pendulum doesn't have issues when entering a control mode.'''<span style="color:red"> Always ensure the pendulum is spotted by a second person when testing so you don't hurt yourself, others in the lab, or the RADA system.</span>''' Once the spotter is ready, run the shell script by using the command ''./1_co3050-11.sh'' in the terminal with the open SSH connection to Eris from the home, ''/root'', directory of Eris. When you run this script there will be a bunch of information printed out about the PIC bus and loading the bit file to configure the FPGA. You will know that RADA is ready for the test when it asks you to select a running mode. See the Testing Modes section below. This script can take a while to complete so beyond the first test after startup you don't need to run this script. See the Section about Running additional tests below.r
[[Image:StartingRADA initial.png|800px]]
=== Testing Modes ===
The RADA system has three testing modes: Robot Control Mode, Tuning Mode, and Box Step Mode. Additionally you can exit the execution at any time by pressing the ''Esc'' key. Once the terminal asks you to chose a mode you can use the following commands to enter the desired mode with a three second delay or exit the program. You can also use these commands to switch between the modes.
-''v'' : Enters the pendulum PID tuning mode, this will only really work when using PIDs to control the pendulum.
-''b'' : Enter Robot control mode, in this mode you can drive the robot around and the pendulum will try to stay vertical. This is the main mode used for testing the whole RADA system.
-''n'' : Enters box step mode, where the pendulum will change its desired pitch and roll angles every 20 seconds and move in a box shape.
-''Esc'' : By hitting the escape key the program will exit the program.
You will almost always want to run Robot Control Mode as the other modes are legacy modes from when we initially built and tested RADA and only works with the pendulum PID controllers. There are also a few utility commands that can be used in all modes.
-''2'' : Resets I composts of the Pitch/Roll PIDs and only the PIDs.
-''m'' : Adds a marker to the Log file incase odd things happen somewhere. This just increments a counter so if you use it look for changes in the marker value.
==== Robot Control Model ====
In Robot control mode you can control the motion of Eris. For PID control of Eris or 1D state feedback system the directional commands command Eris body velocity were for full system and Eris system state feedback controllers control the global velocity. All of these keys only need to be pressed not held down.
-''w'' : Moves Eris forward (+x) at some velocity depending on the controller.
-''s'' : Moves Eris in reverse (-x) at some velocity depending on the controller.
-''d'' : Moves Eris in right (+y) at some velocity depending on the controller.
-''a'' : Moves Eris in left (-y) at some velocity depending on the controller.
-''p'' : Stops the motion of Eris (Set all velocity set points to zero). I.e. if you hit ''w'' then hit ''s'' then Eris will be moving in reverse.
-''y'' : Moves Eris forward and to the right (+x/+y) simultaneously at some velocity depending on the controller.
-''t'' : Moves Eris forward and to the left (+x/-y) simultaneously at some velocity depending on the controller.
-''i'' : Moves Eris reverse and to the right (-x/+y) simultaneously at some velocity depending on the controller.
-''y'' : Moves Eris reverse and to the left (-x/-y) simultaneously at some velocity depending on the controller.
-''e'' : Rotate Eris clockwise (+yaw) at some angular rate. This only worked when RADA used the closed-loop FPGA control of the wheels. There is currently no controllers that use this command.
-''q'' : Rotate Eris counter-clockwise (-yaw) at some angular rate. This only worked when RADA used the closed-loop FPGA control of the wheels. There is currently no controllers that use this command.
-''<'' : Increment Eris' desired heading 45 degrees counter-clockwise (-yaw).
-''>'' : Increment Eris' desired heading 45 degrees clockwise (+yaw).
-''7'' : Increments the pitch set point (+pitch).
-''4'' : Decrements the pitch set point (-pitch).
-''8'' : Increments the roll set point (+roll).
-''5'' : Decrements the roll set point (-roll).
==== Tuning Mode ====
Tuning mode allows you to tune the PID controllers for both pitch and roll. The UI commands here are also available in Box Step Mode.
-''1'' : Tune the Pitch PID.
-''3'' : Tune the Roll PID.
-''7'' : Increase proportional gain of PID being tuned.
-''4'' : Decrease proportional gain of PID being tuned.
-''8'' : Increase integral gain of PID being tuned.
-''5'' : Decrease integral gain of PID being tuned.
-''9'' : Increase derivative gain of PID being tuned.
-''6'' : Decrease derivative gain of PID being tuned.
-''i'' : Increase set point of PID being tuned.
-''k'' : Decrease set point of PID being tuned.
-''o'' : Increase integral windup term of PID being tuned. (Not used)
-''l'' : Decrease integral windup term of PID being tuned. (Not used)
==== Box Step Mode ====
Box set mode will automatically change the set points of the pendulum every 20 seconds. The case statement for this mode can be changed for 1D and 2D step modes. This mode allows the user to use he same commands as Tuning Mode.
=== Running additional Tests ===
Once you have run one test with Eris on it is unnecessary to configure the FPGA or connect to the NFS server again. This is what took much of the time in the initial setup. This is what the script ''3_stat_eris.sh'' was developed for. It does everything that ''1_co3050-11.sh'' does but without reprogramming the FPGA or reconnecting to the NFS server. As a result it is ready to test much quicker.
Before starting the test it is best to have someone spotting the pendulum a holding it near vertical so that the pendulum doesn't have issues when entering a control mode.'''<span style="color:red"> Always run ensure the pendulum is spotted by a second person when testing so you don't hurt yourself, others in the lab, or the RADA system.</span>''' Once you spotter is ready run the shell scrip by= using the command ''./3_start_eris.sh'' in the terminal with the open SSH connection to Eris from the home, ''/root'', directory of Eris.
[[Image:StartingRADA2nd.png|800px]]
=== Locating and retrieving log files ===
If you are only demoing the system there is no need to go beyond this point. Once you are done with a test that you want to compare to the model you should retrieve the log file right away so you don't mix it up with other test. On CO3050-11 go to the dircetory ''/home/shared/MainProject/Logs'' using the file browser (you can do this in a terminal but it is easier from the file explorer). Once there, look for the folder that has been modified most recently as Eris date is normally out of sync with its date and time. Then look for the newest log file. Log files are named like ''log(hh.mm.ss).txt'' (ex. log(13.04.51).txt). This naming convention works well to ensure that no log file is over written but it isn't useful of describing what the test was of or for. Copy this log to the Desktop or to a USB drive and rename it. A good method is to name the file something like ''RADA_ctrl_otherNote#.txt'', where Describes what system you tested (ex. RADA, RADA1D, PEN1D, PEN2D), what typ of controller was used, other notes and then a number if this is a repeat of another test. This is much more useful when looking back at these logs later on. Before transferring the log file for processing you should record the wheel and propeller battery voltages in the header of the log file. The log file format is both human readable and can be parsed by MATALB. It was designed by the first RADA Senior Design Team and more information about the log files can be found [http://wikis.ece.iastate.edu/robotic-agriculture-data-acquisition/index.php/Data_Analysis_Tool here.] See he section below on measuring battery voltage below in order to get the best measurements for simulation of RADA.
=== Measuring battery voltages ===
The last thing that you need to do before simulating an experiment of the RADA platform is record the battery voltages for both the wheels and propellers. The wheel battery can be measured unloaded as there isn't large line losses between the battery and the H-bridges. The propeller battery voltage needs to be measured under load because the power cord running up the pendulum has significant line losses at the currents the propellers draw when in use. The battery voltages can be recorded in the log file for the test. Open the log file for the test you just completed (Use KWrite for Linux machines or Notepad++ for Windows machines). The first few lines of the log is the headder. It should look like this:
#Constants pitch_P pitch_I pitch_D
#PIDValues 48000 18000 21000
#Constants roll_P roll_I roll_D
#PIDValues 48000 18000 21000
#Battery Vquad Vwheels
#Voltage
Follow the procedure for measuring the voltage of each battery and then record the voltage under the corresponding battery. Then save the log file and close out of your text editor and the test will be ready for processing. Recoding the battery voltages in this way makes it much easier to find if you need the value latter. The final log file header should look like this once you are done
#Constants pitch_P pitch_I pitch_D
#PIDValues 48000 18000 21000
#Constants roll_P roll_I roll_D
#PIDValues 48000 18000 21000
#Battery Vquad Vwheels
#Voltage 14.44 8.257
==== Wheel Battery ====
1. After test disconnect wheel battery from the system.
2. Measure voltage of battery using multimeter.
[[Image:MeasureVwheel.jpg|800px]]
You can use the plug used for charging the 2-cell Lipos but make sure to connect the plug to the multimeter before connecting the battery and disconnect the battery before disconnecting the plug from the mulitmeter. It is generally the best practice to give the multimeter a few minutes to allow for the voltage measurement to stabilize as the battery measurement tends to be a little low right after the test. The multimeter will report data out to four decimal places it is best just to round to three decimal places for the wheel voltage.
==== Quad Battery ====
1. Setup code to run all four propellers at 50% throttle, uncomment the definition of ''mot50'' in main.cpp and compile the project.
2. Power off propellers by turning off the switch to the ESCs.
3. Connect multimeter to measure the voltage across one of the ESCs. This is done by using the power splitter cord.
-Connect one of the female XT60 connectors on the splitter to a male XT60 connector to banana connector cable.
-The banana connector connect to the hand held multimeter. The multimeter should be set to the 20VDC measurement setting.
-Next unplug one the ESCs' power connection.
-reconnect the ESC to power through the two remain connectors on the spliter cable.
4. Power on the propellers.
5. Run the system at 50% throttle and measure the steady-state voltage during the test. The battery will slow the voltage decay significantly, meaning it will keep the same measurement for a few seconds.
6. Stop the test and record the voltage in the log file. Make sure to disconnect the batter before removing the splitter cable.
{| class="wikitable" style="text-align:center"
|-
| [[Image:PowerSplitter.jpg|200px]]
| [[Image:QuadMultiCon.jpg |200px]]
| [[Image:QuadMultiSet.JPG |200px]]
| [[Image:QuadMeasESCcon.JPG|200px]]
|-
| Splitter cord.
| Connect splitter to multimeter.
| Settings for multimeter.
| Connecting ESC through splitter.
|}
The testing setup should look like the image below:
[[Image:QuadBattMeas.jpg|800px]]
== Post processing and Simulation ==
Simulating a test of RADA starts with processing and storing the data. Then all of the parameters of the model are loaded in the MATLAB Workspace. Finally the Simulink file used for the simulation is opened and the length of the simulation is set to match the length of the actual test. The simulation is run and the simulation output is stored. Finally the data should be plotted and compared.
=== Using the MATLAB data parsing tool ===
In depth discussion of how to use the log file parsing tool is described [http://wikis.ece.iastate.edu/robotic-agriculture-data-acquisition/index.php/Data_Analysis_Tool here.] I suggest using the version of the tool in the rada_resarch_project git repository Paul Uhing used for his Master's research. It con be found on CO3050-11 under the ucart account in the directory ''~/rada_research_project/DataAnalysiTool_omnicoor/Tool''. Simply open MATLAB and set the working directory to this file path. In the MATLAB Command Prompt run ''DataAnalysis''. A popup window should open up. Select the log file you want to process and wait for the tool to finish processing the file. Once this is complete there should be four structures in the MATLAB workspace.
-'''main''' : This contains all of the data extracted from the log file and the processing parameters used. main.expData contains two time structures: Time is used for the pendulum data and Eris_time is used for the ground vehicle data.
-'''X_ref''' : This contains the reference vector in m/s for x velocity that is feed into Simulink. This expedites the simulation setup process, this used to be done by hand.
-'''Y_ref''' : This contains the reference vector in m/s for y velocity that is feed into Simulink. This expedites the simulation setup process, this used to be done by hand.
-'''Yaw_ref''' : This contains the reference vector in radians for yaw that is feed into Simulink. This expedites the simulation setup process, this used to be done by hand. This one is new incase people start testing the system with heading changes but is not used in the current setup.
The first thing you should do is rename the main structure to the name you used for the log file. This is helpful for comparing multiple tests. Next you will want to crate two new variable ''Vquad_test'' an Vw_test''. In the MATLAB Command Prompt set the measured propeller voltage from the log file to ''Vquad_test'' and set the measured the wheel voltage to ''Vw_test'' as this will be used by the simulation. Finally if you did an open-loop test of the wheels create the variable ''Uol'' and set it to the open-loop wheel command used. Save all of these variables from the MATLAB workspace to a ''.mat'' file of the same name as log file you extracted the data from and save it in the same directory as your RADA Simulink files. As of August 2nd, 2016 this directory is ''~/rada_research_project/MATLAB/RADA.''
=== Setting up the MATLAB workspace for simulation ===
Change your MATLAB directory to this directory. Then run the simulation setup files. Currently you just need to run ''modelParams_smallWheels_RADA'' in the MATLAB Command Prompt. Next open the Simulink file with that contains the model of RADA controlled by the controller you tested.
-'''RADA_psiCtrl_v2_lqi_est.slx''' contains LQI, LQI+estimation, and LQG controller simulations.
-'''RADA_psiCtrl_v2.slx''' contains the PID controlled system.
-'''RADA_psiCtrl_v2_LQGsep.slx''' contains the subsystem LQG controlled system.
-'''RADA_psiCtrl_v2_LQGsep_ol.slx''' contains the simulation of the pendulum system controlled by an LQG and Eris controlled with open-loop commands.
Note all of the current (August 2nd, 2016) ''.slx'' files were created in MATLAB 2014b and will only work in MATLAB 2014B or newer. Then in the MATLAB Command Prompt type ''X_ref.time(end)'' exactly, don't add a semicolon, and hit enter. MATLAB will print the time of the last command in the X_ref structure. Set the en time of the simulation to this value and save your Simulink file.
=== Running simulations and storing results ===
Before running the simulation make sure that the simuation is using the ''ode23t'' differential equations solver. This system is a moderately stiff system of differential and the ''ode45'' solver doesn't do well with these types of systems. When using ''ode23t'' is should only take a few minutes to run a 100+ second simulation while doing the same test using ''ode45'' could take 8 hours. While this slow it is also bad for your hard drive as the simulation has to page between RAM and your computers hard drive a lot.
Once this check is done run the simulation. While it is running check what the output structures variables are named for for your RADA test system. Once the simulation is done go to your MATLAB Workspace and select all 15 outputs for your simulation or your sub-simulation if you used '''RADA_psiCtrl_v2_lqi_est.slx'''. Save these 15 output structures to a ''.mat'' file named as the log file with _sim appended to the end of the name.
The 15 outputs are structures containing a time vector and then the data from the simulation sampled at 100 Hz and the units of this data are the SI units (ex: radians, m/s). There is one output structure for x velocity, y velocity, x body velocity, y body velocity, theta (pitch), phi (roll), psi (yaw), and one per actuator command (ex: the command sent to a wheel). Now you have all the data you can plot it.
=== Plotting results ===
If you look at the ''DataSets'' folder below ''~/rada_research_project/MATLAB/RADA'' directory there are plenty of examples of how Paul Uhing compared simulation to test data. Generally you should grate a ''.m'' file with the same name as the log file this data was extracted from with _plot appended to the name.
Generally you can just copy an for RADA_LQG_compPID_plot.m RADA_PID_compLQG_plot.m, RADA_LQG_sep_plot.m, or RADA_LQG_sep_ol_plot.m files and rename the structures for your test.
These files create four figures. Figure 1 plots compares the x velocity data in the first sub figure and compares pitch (theta) data in the second sub figure. Figure 2 does the same thing as Figure 1 but with y velocity and roll data. Figure 3 looks at the yaw data. Finally, Figure 4 looks at the sample period between UAV and ERIS packets from the camera system just to check for periods of time with large packet drops.
You can follow a similar pattern to compare motor commands. Just make sure that you compare Quad Motor 2 from the test data with Quad Motor 4 from simulation and vise versa because propellers 2 and 4 were switch in Eris's software compared to the Model.
That is all you need to know for testing RADA against the model.
4fc976173e5a88c6e8cdb555506741bde4dbfdda
339
338
2016-09-21T23:35:51Z
Jonessk
7
/* Connecting to RADA */
wikitext
text/x-wiki
This page will take you though setting up and testing RADA, retrieving the log file and other necessary data to run a simulation of that test and processing the data in MATLAB. Then actually running the simulation of RADA in Simulink. The initial setup and how to test the system can also be applied to demoing RADA.
== Setting Up a RADA Test ==
Testing RADA is not overly difficult once you get the hang of the steps to setup RADA. The following steps may seem like a long process to go from starting the testing process to having completed simulation and plotting of the test results but this whole test procedure (with the exception of battery charging) can be completed in about 15-20 minutes. These steps are meant to be as detailed as possible in order to help new users of RADA get up and running as quickly as possible.
'''<span style="color:red">NOTE: Always run RADA with at least 2 people!</span>''' The pendulum arm can crash into the ground if the network starts to drop packets and one person cannot give commands to RADA and spot the pendulum. This is a safety issue for both you and the RADA platform.
=== Charging Batteries ===
The lab currently uses mostly Hyperion batteries. We charge our batteries with a Hyperion EOS 1420i Net3 battery charger. For some general information about how to use this charger see [https://www.youtube.com/watch?v=-ox3EpzvsJ8 this video.]. In the lab we power this charger using the old Kepco Power supply because it is the only power supply that can supply enough current. Make sure that the power supply is set to an output voltage between 10.5V-29V.
{| class="wikitable" style="text-align:center"
|-
| [[Image:ChargerPowerSupplyOff.JPG|400px]]
| [[Image:ChargerPowerSuplyOn.JPG|400px]]
|-
| Kepco Power Supply off.
| Kepco Power Supply on with correct voltage supply range.
|}
The YouTube video link above should explain how to use the charger. RADA currently uses three different Lithium polymer (Lipo) batteries: 1600 mAh 2-cell Lipo for the wheels, 2600 mAh 2-cell Lipo for the electronics of Eris, and a 2600 mAh 4-cell Lipo for the propellers. The 1600 mAh 2-cell Lipo can be charged using memory slot 2 of the charger. The 2600 mAh 2-cell Lipos can be charged using memory slot 3 for fast charging and memory slot 4 for slower charging (use this if the battery voltage drops really low for 10-20 minutes then switch to fast charging). The 2600 mAh 4-cell Lipo can be charged using memory slot 8. The 1600 mAh 2-cell and 2600 mAh 4-cell generally charge in 10-20 minutes apiece while the 2600 mAh 2-cell generally take up to 70 minutes to charge fully.
=== Setting up the Camera System ===
The camera system is run on the windows computer CO3050-07. You can log into this computer using a local microcart username and password (not posted here for security reasons, but any one who works in the lab should know it). Once logged in, look for Tracking Tools in the start menu or look for the shortcut shown below:
[[Image:TrackingTools_shortcut.PNG|thumb|center|Tracking Tools shortcut]]
Once the program opens the screen should look something like this:
[[Image:NewTrackingTools.PNG|800px]]
In the Tracking Tools Quick Start pop up menu select Open Existing Project and then navigate to ''D:\Optitrack_Configuration'' (It should open to this directory by default) and select the most recent Tracking Tools project. It should have the naming scheme ''TrackingToolsProject YYYY-MM-DD timeStamp.ttp''. This is normally the most recently edited file when sorting by date modified. The most recent one as of August 1st, 2016 is ''TrackingToolsProject 2015-09-23 2.30pm.ttp''.
[[Image:OpeningProject.PNG|800px]]
You should notice that the cameras shown in the main project screen arrange themselves like the camera system configuration once the project has been opened. Now the constellations need to be loaded. This can be done by going to ''File->Open'' and another popup window will open. Navigate back to ''D:\Optitrack_Configuration'' (It should open to this directory by default) and select the most recently dated set of RADA trackables. They have the naming scheme ''RADA_entireSystem_M_D_YYYY.tra''. The most recent one as of August 1st, 2016 is ''RADA_entireSystem_7_8_2016.tra''.
[[Image:Opening_trackables.PNG|800px]]
Once the project and trackables are open, the cameras should appear in their constellation (square) and there should be two constellations under ''Project Explorer->Trackables''. One named UAV for the pendulum and one named ERIS for the ground vehicle. In order to get additional information about each constellation, left click on the the name of the desired trackable.
[[Image:SelectingUAV.PNG|800px]]
Once a trackable is selected more information about it is available in the ''Trackables'' Tab on the right side of the screen. For the current position and orientation look at the ''Real-Time Info'' sub-tab. This gives the orientation in the wrong order for how we currently use the Euler angles. When two or three of the angles are near zero you can switch yaw and pitch to get roughly the correct orientation.
[[Image:Uav_realTimeInfo.PNG|800px]]
Now we need to check to make sure the system is zeroed.
#Hold RADA so that the front of the ground robot (ERIS is facing the wall with the white boards (east)). The front side of Eris is labeled. If it isn't, the front is the side opposite the switches and the side with the trackable constellation on it.
#Make sure that the motor with the red motor mount is also facing the wall with the white boards.
#Make sure the quad system is aligned along Eris Axis by standing behind the system. If the system is aligned, you should be able to block the mounting bolts of the front propeller motor with the pole while facing the east wall.
#While holding the pendulum approximately vertical, see if the camera system reads zeros for the pendulum (UAV) pitch and roll (yaw and roll in ''Real-Time Info''). If yaw is off by a few degrees that is fine.
#Compare the yaw of the UAV to that of ERIS (Remember this is pitch in ''Real-Time Info''). If they are both near zero and within a few degrees and the pendulum's pitch/roll were also near zero then you are ready to use the camera system. Otherwise, go to the next step.
#You need to zero the pendulum.
##Align ERIS so it is near zero yaw first (eye ball it).
##Get a level and a friend. Have your friend use a level to ensure that the pendulum is level in both directions and hold it there.
##With the UAV constellation selected go to the ''Orientation'' tab (next to ''Real-Time Info'' tab) and click on ''Reset To Current Orientation'' button
##Now your friend can set the pendulum down and you can zero ERIS the same way.
#Save the new trackable orientation by going to ''File->Save Trackables...'' and save a file using the same naming conventions as the trackable file you opened earlier. Use the current data so you don't have to re-zero the system the next time you test.
[[Image:Uav_ResetOrientation.PNG|800px]]
=== Building Software ===
The development environment for running RADA is hosted on CO3050-11, a Linux Red Hat environment. This computer has a local ucart user name that you should use (the password isn't put here for security reasons). First, ensure that the RADA software is setup correctly for the test you want to run. To do this, you will need to open the main.cpp and logger.cpp files and make sure all of the compile time macros you want are defined correctly. All of the c++ files you should need to edit are in the directory ''~/Desktop/rada_research_project/ErisResearchCode/CppProjects/MainProgram_PacketLoss/src/Korebot'' Below are compiler macro options for main.cpp:
-'''H2ctrl''' : This will cause the system to enter H2 controller mode where the whole RADA system is controlled by an H2 controller.
-'''ssTracking''' : H2ctrl must also be defined for this macro to do anything. This macro will has the system to be controlled by a tracking H2 controller.
-'''ssMotors''' : H2ctrl must also be defined for this macro to do anything. This macro will has the system to be controlled by an H2 contorller that contains propeller states. This also causes the system to "Dance."
-'''ssDrop''' : Cause the system to go into packet drop controller mode. This mode allows controllers designed for lossy networks to be tested. Based off of other definitions how lossy the network is can be simulated. If nothing else is defined this controller becomes basically a H2 controller.
-'''drop10''' : Will put the packet drop mode into 10% loss mode and use a controller designed for 10% loss.
-'''drop30''' : Will put the packet drop mode into 30% loss mode and use a controller designed for 30% loss.
-'''drop50''' : Will put the packet drop mode into 50% loss mode and use a controller designed for 50% loss.
-'''mot50''' : This macro over-rides all other macros. If this is turned on the wheels will not run and the propellers will be run at 50% command. This is used for measuring the effective battery voltage seen by the ESCs. This is always run after a test.
-'''RADAlqi''' : This macro will cause the system to use an LQI controller on the whole system. The linear velocity states are calculated with no filter and the angular velocity states are calculated with filters.
-'''RADAlqi_est''' : This macro will cause the system to use an LQI controller on the whole system. A traditional estimator is used to estimate the states.
-'''rada_lqg''' : This macro will cause the entire system to be controlled by an LQG controller/estimator system.
-'''rada_split_lqg''' : This macro will cause the pendulum and ground robot to be controlled by their own LQG systems.
-'''rada_split_lqg_ol''' : This macro will cause the pendulum to be controlled by an LQG controller, the yaw of the ground robot to be controlled by a PID controller, and the ground robot linear velocities to be controlled with open-loop commands.
-'''yaw_off''' : This macro will cause the yaw control to be disabled on some controllers.
*'''accR''' : This macro will cause the PID linear velocity controllers to be given ramps to accelerate from one velocity to another instead of steps.
-'''posRamp''' : This macro will cause the linear velocities of RADA to be controlled by position PIDs with ramp reference instead of velocity commands.
-If no controller selection is made all controllers revert to PID controllers
All of these macros can be defined simply by uncommenting the corresponding define statement in main.cpp. The macros in the logger.cpp can be seen below:
-'''ssDrop''' : This macro puts the logger into packet drop controller mode and logs the correct values for the packet drop controllers.
-'''RADAlqi''' : This macro puts the logger into full system LQI controller logging mode.
-'''RADAlqi_est''' : This macro puts the logger into full system LQI controller plus estimator logging mode.
-'''rada_lqg''' : This puts the logger into full system LQG controller logging mode.
-'''rada_split_lqg''' : This macro causes the logger to log data about the subsystem LQG controllers.
-'''rada_split_lqg_ol''' : This cause the system to log data about the pendulum LQG system and the open-loop linear velocity commands.
-'''H2ctrl''' : This macro causes the logger to log data about the full system H2 controllers.
-If no logging mode is selected then the logger will default to logging PID data.
Because the system only calculates controllers for one set of controllers it is important to ensure that the logger is in the correct mode based off of what is defined in main.cpp. As of August 1st, 2016 the defines in main.cpp are not seen in logger.cpp.
Finally in a command prompt navigate to the driectroy: ''~/Desktop/rada_research_project/ErisResearchCode/CppProjects/MainProgram_PacketLoss''
Here just type: ''make''. The code will compile for your desired mode. For setting up a new development directory see [http://wikis.ece.iastate.edu/robotic-agriculture-data-acquisition/index.php/Setting_up_a_new_development_environment Setting up a new development environment] from the RADA Senior Design wiki.
[[Image:ComplingRADACode.png|800px]]
The complied executable code ends up in ''/home/shared/MainProject''. The ''/home/shared'' directory is setup as a network file share (NFS).
[[Image:ErisCompliedCode-config.png|800px]]
This service needs to be restarted when CO3050-11 is restarted. [http://wikis.ece.iastate.edu/robotic-agriculture-data-acquisition/index.php/Configuring_NFS_shares_for_the_robot Configure NFS shares for the robot] from the RADA Senior Design wiki. Be sure to use the new Linux install command in step six. Though I have found that even on a good strt the ''[ok]'' messages will still print.
=== Turning on RADA ===
Turning on Eris is fairly simple. Each system has its own battery. There is one for the wheels that plugs in at the front of Eris (opposite side of the switches), one for the electronics in the back of Eris (in between the switches), and one for the propellers that goes on top of Eris.
[[Image:ErisOnPhoto.jpg|800px]]
The wheel battery is normally 1600 mAh 2-cell Lipo but any 2-cell Lipo will work. The wheels are turned on by flipping the silver switch so the top points away from the system. The electronics normally use a 2600 mAh 2-cell Lipo. The electronics are turned on by flipping the green switch away from the system. It is important that you use EITHER the WIFI adapter OR hardwired Ethernet, because the VRPN may listen to the camera data broadcast over both connections which could cause problems. The propeller system is powered via a 2600 mAh 4-cell Lipo that connects to a power cable at the base of the pendulum. There is a switch to turn on the power to the propellers system. You will know it is on when the 1 on the switch is flush with the switch housing instead of sticking out. It takes about 30 seconds to a minute for Eris to boot up and start the networking connections. When the WIFI is plugged in, you will know it is ready when a blue light turns on, on the module.
=== Connecting to RADA ===
RADA is controlled through an SSH connection in a command prompt. This is not the one you compile the code from so that you can recompile for different setup without needing to close the connection. If you are using a WIFI connection, use the command ''ssh root@192.168.0.53''. If you are connected to Eris through a LAN connection use the command ''ssh root@192.168.0.54''. If the connection goes though you should be prompted for a password.
The password is ''rootme''.
[[Image:Ssh2Eris.png|800px]]
It is important to close the SSH connection before turning off Eris because the terminal you are using will hang up if you don't. You can close the connection by using the command ''exit''.
[[Image:ClosingSSH.png|800px]]
== Testing RADA ==
Now that you are connected to Eris you can run tests. The testing is started by a few different methods.
=== Running the First Test After Power Up ===
For the first test after powering on Eris, a few additional steps need to be completed in order to test the system. The FPGA motor controller needs to be programmed and Eris needs to connect to the NFS server running on CO3050-11. This is accomplished by running ''1_co3050-11.sh'', this shell script will setup the NFS, and load the bit file into the FPGA configuration memory. Then it retrieves the executable file from the NFS server ''/mnt/nfs/MainProject'' and runs the executable. Once the user exits the executable, the log file produced is copied from the ''~/Logs/YYYY_MM_DD_Day'' directory on Eris to ''/home/shared/MainProject/Logs/YYYY_MM_DD_Day'' on CO3050-11. When the folder for the current Eris date doesn't exist it creates this directory in CO3050-11 and then removes the directory and log file from Eris. You may see a warning that when copying the log file Eris couldn't maintain the file permission settings. This is normal as Eris doesn't have the same access to the NSF server as it has to its own files. This date stamp uses the date on Eris, which is currently in June of 2008 as of August 2nd, 2016.
Before starting the test, it is best to have someone spotting the pendulum and holding it near vertical so that the pendulum doesn't have issues when entering a control mode.'''<span style="color:red"> Always ensure the pendulum is spotted by a second person when testing so you don't hurt yourself, others in the lab, or the RADA system.</span>''' Once the spotter is ready, run the shell script by using the command ''./1_co3050-11.sh'' in the terminal with the open SSH connection to Eris from the home, ''/root'', directory of Eris. When you run this script there will be a bunch of information printed out about the PIC bus and loading the bit file to configure the FPGA. You will know that RADA is ready for the test when it asks you to select a running mode. See the Testing Modes section below. This script can take a while to complete so beyond the first test after startup you don't need to run this script. See the Section about Running additional tests below.r
[[Image:StartingRADA initial.png|800px]]
=== Testing Modes ===
The RADA system has three testing modes: Robot Control Mode, Tuning Mode, and Box Step Mode. Additionally you can exit the execution at any time by pressing the ''Esc'' key. Once the terminal asks you to chose a mode you can use the following commands to enter the desired mode with a three second delay or exit the program. You can also use these commands to switch between the modes.
-''v'' : Enters the pendulum PID tuning mode, this will only really work when using PIDs to control the pendulum.
-''b'' : Enter Robot control mode, in this mode you can drive the robot around and the pendulum will try to stay vertical. This is the main mode used for testing the whole RADA system.
-''n'' : Enters box step mode, where the pendulum will change its desired pitch and roll angles every 20 seconds and move in a box shape.
-''Esc'' : By hitting the escape key the program will exit the program.
You will almost always want to run Robot Control Mode as the other modes are legacy modes from when we initially built and tested RADA and only works with the pendulum PID controllers. There are also a few utility commands that can be used in all modes.
-''2'' : Resets I composts of the Pitch/Roll PIDs and only the PIDs.
-''m'' : Adds a marker to the Log file incase odd things happen somewhere. This just increments a counter so if you use it look for changes in the marker value.
==== Robot Control Model ====
In Robot control mode you can control the motion of Eris. For PID control of Eris or 1D state feedback system the directional commands command Eris body velocity were for full system and Eris system state feedback controllers control the global velocity. All of these keys only need to be pressed not held down.
-''w'' : Moves Eris forward (+x) at some velocity depending on the controller.
-''s'' : Moves Eris in reverse (-x) at some velocity depending on the controller.
-''d'' : Moves Eris in right (+y) at some velocity depending on the controller.
-''a'' : Moves Eris in left (-y) at some velocity depending on the controller.
-''p'' : Stops the motion of Eris (Set all velocity set points to zero). I.e. if you hit ''w'' then hit ''s'' then Eris will be moving in reverse.
-''y'' : Moves Eris forward and to the right (+x/+y) simultaneously at some velocity depending on the controller.
-''t'' : Moves Eris forward and to the left (+x/-y) simultaneously at some velocity depending on the controller.
-''i'' : Moves Eris reverse and to the right (-x/+y) simultaneously at some velocity depending on the controller.
-''y'' : Moves Eris reverse and to the left (-x/-y) simultaneously at some velocity depending on the controller.
-''e'' : Rotate Eris clockwise (+yaw) at some angular rate. This only worked when RADA used the closed-loop FPGA control of the wheels. There is currently no controllers that use this command.
-''q'' : Rotate Eris counter-clockwise (-yaw) at some angular rate. This only worked when RADA used the closed-loop FPGA control of the wheels. There is currently no controllers that use this command.
-''<'' : Increment Eris' desired heading 45 degrees counter-clockwise (-yaw).
-''>'' : Increment Eris' desired heading 45 degrees clockwise (+yaw).
-''7'' : Increments the pitch set point (+pitch).
-''4'' : Decrements the pitch set point (-pitch).
-''8'' : Increments the roll set point (+roll).
-''5'' : Decrements the roll set point (-roll).
==== Tuning Mode ====
Tuning mode allows you to tune the PID controllers for both pitch and roll. The UI commands here are also available in Box Step Mode.
-''1'' : Tune the Pitch PID.
-''3'' : Tune the Roll PID.
-''7'' : Increase proportional gain of PID being tuned.
-''4'' : Decrease proportional gain of PID being tuned.
-''8'' : Increase integral gain of PID being tuned.
-''5'' : Decrease integral gain of PID being tuned.
-''9'' : Increase derivative gain of PID being tuned.
-''6'' : Decrease derivative gain of PID being tuned.
-''i'' : Increase set point of PID being tuned.
-''k'' : Decrease set point of PID being tuned.
-''o'' : Increase integral windup term of PID being tuned. (Not used)
-''l'' : Decrease integral windup term of PID being tuned. (Not used)
==== Box Step Mode ====
Box set mode will automatically change the set points of the pendulum every 20 seconds. The case statement for this mode can be changed for 1D and 2D step modes. This mode allows the user to use he same commands as Tuning Mode.
=== Running additional Tests ===
Once you have run one test with Eris on it is unnecessary to configure the FPGA or connect to the NFS server again. This is what took much of the time in the initial setup. This is what the script ''3_stat_eris.sh'' was developed for. It does everything that ''1_co3050-11.sh'' does but without reprogramming the FPGA or reconnecting to the NFS server. As a result it is ready to test much quicker.
Before starting the test it is best to have someone spotting the pendulum a holding it near vertical so that the pendulum doesn't have issues when entering a control mode.'''<span style="color:red"> Always run ensure the pendulum is spotted by a second person when testing so you don't hurt yourself, others in the lab, or the RADA system.</span>''' Once you spotter is ready run the shell scrip by= using the command ''./3_start_eris.sh'' in the terminal with the open SSH connection to Eris from the home, ''/root'', directory of Eris.
[[Image:StartingRADA2nd.png|800px]]
=== Locating and retrieving log files ===
If you are only demoing the system there is no need to go beyond this point. Once you are done with a test that you want to compare to the model you should retrieve the log file right away so you don't mix it up with other test. On CO3050-11 go to the dircetory ''/home/shared/MainProject/Logs'' using the file browser (you can do this in a terminal but it is easier from the file explorer). Once there, look for the folder that has been modified most recently as Eris date is normally out of sync with its date and time. Then look for the newest log file. Log files are named like ''log(hh.mm.ss).txt'' (ex. log(13.04.51).txt). This naming convention works well to ensure that no log file is over written but it isn't useful of describing what the test was of or for. Copy this log to the Desktop or to a USB drive and rename it. A good method is to name the file something like ''RADA_ctrl_otherNote#.txt'', where Describes what system you tested (ex. RADA, RADA1D, PEN1D, PEN2D), what typ of controller was used, other notes and then a number if this is a repeat of another test. This is much more useful when looking back at these logs later on. Before transferring the log file for processing you should record the wheel and propeller battery voltages in the header of the log file. The log file format is both human readable and can be parsed by MATALB. It was designed by the first RADA Senior Design Team and more information about the log files can be found [http://wikis.ece.iastate.edu/robotic-agriculture-data-acquisition/index.php/Data_Analysis_Tool here.] See he section below on measuring battery voltage below in order to get the best measurements for simulation of RADA.
=== Measuring battery voltages ===
The last thing that you need to do before simulating an experiment of the RADA platform is record the battery voltages for both the wheels and propellers. The wheel battery can be measured unloaded as there isn't large line losses between the battery and the H-bridges. The propeller battery voltage needs to be measured under load because the power cord running up the pendulum has significant line losses at the currents the propellers draw when in use. The battery voltages can be recorded in the log file for the test. Open the log file for the test you just completed (Use KWrite for Linux machines or Notepad++ for Windows machines). The first few lines of the log is the headder. It should look like this:
#Constants pitch_P pitch_I pitch_D
#PIDValues 48000 18000 21000
#Constants roll_P roll_I roll_D
#PIDValues 48000 18000 21000
#Battery Vquad Vwheels
#Voltage
Follow the procedure for measuring the voltage of each battery and then record the voltage under the corresponding battery. Then save the log file and close out of your text editor and the test will be ready for processing. Recoding the battery voltages in this way makes it much easier to find if you need the value latter. The final log file header should look like this once you are done
#Constants pitch_P pitch_I pitch_D
#PIDValues 48000 18000 21000
#Constants roll_P roll_I roll_D
#PIDValues 48000 18000 21000
#Battery Vquad Vwheels
#Voltage 14.44 8.257
==== Wheel Battery ====
1. After test disconnect wheel battery from the system.
2. Measure voltage of battery using multimeter.
[[Image:MeasureVwheel.jpg|800px]]
You can use the plug used for charging the 2-cell Lipos but make sure to connect the plug to the multimeter before connecting the battery and disconnect the battery before disconnecting the plug from the mulitmeter. It is generally the best practice to give the multimeter a few minutes to allow for the voltage measurement to stabilize as the battery measurement tends to be a little low right after the test. The multimeter will report data out to four decimal places it is best just to round to three decimal places for the wheel voltage.
==== Quad Battery ====
1. Setup code to run all four propellers at 50% throttle, uncomment the definition of ''mot50'' in main.cpp and compile the project.
2. Power off propellers by turning off the switch to the ESCs.
3. Connect multimeter to measure the voltage across one of the ESCs. This is done by using the power splitter cord.
-Connect one of the female XT60 connectors on the splitter to a male XT60 connector to banana connector cable.
-The banana connector connect to the hand held multimeter. The multimeter should be set to the 20VDC measurement setting.
-Next unplug one the ESCs' power connection.
-reconnect the ESC to power through the two remain connectors on the spliter cable.
4. Power on the propellers.
5. Run the system at 50% throttle and measure the steady-state voltage during the test. The battery will slow the voltage decay significantly, meaning it will keep the same measurement for a few seconds.
6. Stop the test and record the voltage in the log file. Make sure to disconnect the batter before removing the splitter cable.
{| class="wikitable" style="text-align:center"
|-
| [[Image:PowerSplitter.jpg|200px]]
| [[Image:QuadMultiCon.jpg |200px]]
| [[Image:QuadMultiSet.JPG |200px]]
| [[Image:QuadMeasESCcon.JPG|200px]]
|-
| Splitter cord.
| Connect splitter to multimeter.
| Settings for multimeter.
| Connecting ESC through splitter.
|}
The testing setup should look like the image below:
[[Image:QuadBattMeas.jpg|800px]]
== Post processing and Simulation ==
Simulating a test of RADA starts with processing and storing the data. Then all of the parameters of the model are loaded in the MATLAB Workspace. Finally the Simulink file used for the simulation is opened and the length of the simulation is set to match the length of the actual test. The simulation is run and the simulation output is stored. Finally the data should be plotted and compared.
=== Using the MATLAB data parsing tool ===
In depth discussion of how to use the log file parsing tool is described [http://wikis.ece.iastate.edu/robotic-agriculture-data-acquisition/index.php/Data_Analysis_Tool here.] I suggest using the version of the tool in the rada_resarch_project git repository Paul Uhing used for his Master's research. It con be found on CO3050-11 under the ucart account in the directory ''~/rada_research_project/DataAnalysiTool_omnicoor/Tool''. Simply open MATLAB and set the working directory to this file path. In the MATLAB Command Prompt run ''DataAnalysis''. A popup window should open up. Select the log file you want to process and wait for the tool to finish processing the file. Once this is complete there should be four structures in the MATLAB workspace.
-'''main''' : This contains all of the data extracted from the log file and the processing parameters used. main.expData contains two time structures: Time is used for the pendulum data and Eris_time is used for the ground vehicle data.
-'''X_ref''' : This contains the reference vector in m/s for x velocity that is feed into Simulink. This expedites the simulation setup process, this used to be done by hand.
-'''Y_ref''' : This contains the reference vector in m/s for y velocity that is feed into Simulink. This expedites the simulation setup process, this used to be done by hand.
-'''Yaw_ref''' : This contains the reference vector in radians for yaw that is feed into Simulink. This expedites the simulation setup process, this used to be done by hand. This one is new incase people start testing the system with heading changes but is not used in the current setup.
The first thing you should do is rename the main structure to the name you used for the log file. This is helpful for comparing multiple tests. Next you will want to crate two new variable ''Vquad_test'' an Vw_test''. In the MATLAB Command Prompt set the measured propeller voltage from the log file to ''Vquad_test'' and set the measured the wheel voltage to ''Vw_test'' as this will be used by the simulation. Finally if you did an open-loop test of the wheels create the variable ''Uol'' and set it to the open-loop wheel command used. Save all of these variables from the MATLAB workspace to a ''.mat'' file of the same name as log file you extracted the data from and save it in the same directory as your RADA Simulink files. As of August 2nd, 2016 this directory is ''~/rada_research_project/MATLAB/RADA.''
=== Setting up the MATLAB workspace for simulation ===
Change your MATLAB directory to this directory. Then run the simulation setup files. Currently you just need to run ''modelParams_smallWheels_RADA'' in the MATLAB Command Prompt. Next open the Simulink file with that contains the model of RADA controlled by the controller you tested.
-'''RADA_psiCtrl_v2_lqi_est.slx''' contains LQI, LQI+estimation, and LQG controller simulations.
-'''RADA_psiCtrl_v2.slx''' contains the PID controlled system.
-'''RADA_psiCtrl_v2_LQGsep.slx''' contains the subsystem LQG controlled system.
-'''RADA_psiCtrl_v2_LQGsep_ol.slx''' contains the simulation of the pendulum system controlled by an LQG and Eris controlled with open-loop commands.
Note all of the current (August 2nd, 2016) ''.slx'' files were created in MATLAB 2014b and will only work in MATLAB 2014B or newer. Then in the MATLAB Command Prompt type ''X_ref.time(end)'' exactly, don't add a semicolon, and hit enter. MATLAB will print the time of the last command in the X_ref structure. Set the en time of the simulation to this value and save your Simulink file.
=== Running simulations and storing results ===
Before running the simulation make sure that the simuation is using the ''ode23t'' differential equations solver. This system is a moderately stiff system of differential and the ''ode45'' solver doesn't do well with these types of systems. When using ''ode23t'' is should only take a few minutes to run a 100+ second simulation while doing the same test using ''ode45'' could take 8 hours. While this slow it is also bad for your hard drive as the simulation has to page between RAM and your computers hard drive a lot.
Once this check is done run the simulation. While it is running check what the output structures variables are named for for your RADA test system. Once the simulation is done go to your MATLAB Workspace and select all 15 outputs for your simulation or your sub-simulation if you used '''RADA_psiCtrl_v2_lqi_est.slx'''. Save these 15 output structures to a ''.mat'' file named as the log file with _sim appended to the end of the name.
The 15 outputs are structures containing a time vector and then the data from the simulation sampled at 100 Hz and the units of this data are the SI units (ex: radians, m/s). There is one output structure for x velocity, y velocity, x body velocity, y body velocity, theta (pitch), phi (roll), psi (yaw), and one per actuator command (ex: the command sent to a wheel). Now you have all the data you can plot it.
=== Plotting results ===
If you look at the ''DataSets'' folder below ''~/rada_research_project/MATLAB/RADA'' directory there are plenty of examples of how Paul Uhing compared simulation to test data. Generally you should grate a ''.m'' file with the same name as the log file this data was extracted from with _plot appended to the name.
Generally you can just copy an for RADA_LQG_compPID_plot.m RADA_PID_compLQG_plot.m, RADA_LQG_sep_plot.m, or RADA_LQG_sep_ol_plot.m files and rename the structures for your test.
These files create four figures. Figure 1 plots compares the x velocity data in the first sub figure and compares pitch (theta) data in the second sub figure. Figure 2 does the same thing as Figure 1 but with y velocity and roll data. Figure 3 looks at the yaw data. Finally, Figure 4 looks at the sample period between UAV and ERIS packets from the camera system just to check for periods of time with large packet drops.
You can follow a similar pattern to compare motor commands. Just make sure that you compare Quad Motor 2 from the test data with Quad Motor 4 from simulation and vise versa because propellers 2 and 4 were switch in Eris's software compared to the Model.
That is all you need to know for testing RADA against the model.
7a58f6f4d227d60dc7a63cb9eea8039f861024b7
340
339
2016-09-21T23:51:49Z
Jonessk
7
/* Testing RADA */
wikitext
text/x-wiki
This page will take you though setting up and testing RADA, retrieving the log file and other necessary data to run a simulation of that test and processing the data in MATLAB. Then actually running the simulation of RADA in Simulink. The initial setup and how to test the system can also be applied to demoing RADA.
== Setting Up a RADA Test ==
Testing RADA is not overly difficult once you get the hang of the steps to setup RADA. The following steps may seem like a long process to go from starting the testing process to having completed simulation and plotting of the test results but this whole test procedure (with the exception of battery charging) can be completed in about 15-20 minutes. These steps are meant to be as detailed as possible in order to help new users of RADA get up and running as quickly as possible.
'''<span style="color:red">NOTE: Always run RADA with at least 2 people!</span>''' The pendulum arm can crash into the ground if the network starts to drop packets and one person cannot give commands to RADA and spot the pendulum. This is a safety issue for both you and the RADA platform.
=== Charging Batteries ===
The lab currently uses mostly Hyperion batteries. We charge our batteries with a Hyperion EOS 1420i Net3 battery charger. For some general information about how to use this charger see [https://www.youtube.com/watch?v=-ox3EpzvsJ8 this video.]. In the lab we power this charger using the old Kepco Power supply because it is the only power supply that can supply enough current. Make sure that the power supply is set to an output voltage between 10.5V-29V.
{| class="wikitable" style="text-align:center"
|-
| [[Image:ChargerPowerSupplyOff.JPG|400px]]
| [[Image:ChargerPowerSuplyOn.JPG|400px]]
|-
| Kepco Power Supply off.
| Kepco Power Supply on with correct voltage supply range.
|}
The YouTube video link above should explain how to use the charger. RADA currently uses three different Lithium polymer (Lipo) batteries: 1600 mAh 2-cell Lipo for the wheels, 2600 mAh 2-cell Lipo for the electronics of Eris, and a 2600 mAh 4-cell Lipo for the propellers. The 1600 mAh 2-cell Lipo can be charged using memory slot 2 of the charger. The 2600 mAh 2-cell Lipos can be charged using memory slot 3 for fast charging and memory slot 4 for slower charging (use this if the battery voltage drops really low for 10-20 minutes then switch to fast charging). The 2600 mAh 4-cell Lipo can be charged using memory slot 8. The 1600 mAh 2-cell and 2600 mAh 4-cell generally charge in 10-20 minutes apiece while the 2600 mAh 2-cell generally take up to 70 minutes to charge fully.
=== Setting up the Camera System ===
The camera system is run on the windows computer CO3050-07. You can log into this computer using a local microcart username and password (not posted here for security reasons, but any one who works in the lab should know it). Once logged in, look for Tracking Tools in the start menu or look for the shortcut shown below:
[[Image:TrackingTools_shortcut.PNG|thumb|center|Tracking Tools shortcut]]
Once the program opens the screen should look something like this:
[[Image:NewTrackingTools.PNG|800px]]
In the Tracking Tools Quick Start pop up menu select Open Existing Project and then navigate to ''D:\Optitrack_Configuration'' (It should open to this directory by default) and select the most recent Tracking Tools project. It should have the naming scheme ''TrackingToolsProject YYYY-MM-DD timeStamp.ttp''. This is normally the most recently edited file when sorting by date modified. The most recent one as of August 1st, 2016 is ''TrackingToolsProject 2015-09-23 2.30pm.ttp''.
[[Image:OpeningProject.PNG|800px]]
You should notice that the cameras shown in the main project screen arrange themselves like the camera system configuration once the project has been opened. Now the constellations need to be loaded. This can be done by going to ''File->Open'' and another popup window will open. Navigate back to ''D:\Optitrack_Configuration'' (It should open to this directory by default) and select the most recently dated set of RADA trackables. They have the naming scheme ''RADA_entireSystem_M_D_YYYY.tra''. The most recent one as of August 1st, 2016 is ''RADA_entireSystem_7_8_2016.tra''.
[[Image:Opening_trackables.PNG|800px]]
Once the project and trackables are open, the cameras should appear in their constellation (square) and there should be two constellations under ''Project Explorer->Trackables''. One named UAV for the pendulum and one named ERIS for the ground vehicle. In order to get additional information about each constellation, left click on the the name of the desired trackable.
[[Image:SelectingUAV.PNG|800px]]
Once a trackable is selected more information about it is available in the ''Trackables'' Tab on the right side of the screen. For the current position and orientation look at the ''Real-Time Info'' sub-tab. This gives the orientation in the wrong order for how we currently use the Euler angles. When two or three of the angles are near zero you can switch yaw and pitch to get roughly the correct orientation.
[[Image:Uav_realTimeInfo.PNG|800px]]
Now we need to check to make sure the system is zeroed.
#Hold RADA so that the front of the ground robot (ERIS is facing the wall with the white boards (east)). The front side of Eris is labeled. If it isn't, the front is the side opposite the switches and the side with the trackable constellation on it.
#Make sure that the motor with the red motor mount is also facing the wall with the white boards.
#Make sure the quad system is aligned along Eris Axis by standing behind the system. If the system is aligned, you should be able to block the mounting bolts of the front propeller motor with the pole while facing the east wall.
#While holding the pendulum approximately vertical, see if the camera system reads zeros for the pendulum (UAV) pitch and roll (yaw and roll in ''Real-Time Info''). If yaw is off by a few degrees that is fine.
#Compare the yaw of the UAV to that of ERIS (Remember this is pitch in ''Real-Time Info''). If they are both near zero and within a few degrees and the pendulum's pitch/roll were also near zero then you are ready to use the camera system. Otherwise, go to the next step.
#You need to zero the pendulum.
##Align ERIS so it is near zero yaw first (eye ball it).
##Get a level and a friend. Have your friend use a level to ensure that the pendulum is level in both directions and hold it there.
##With the UAV constellation selected go to the ''Orientation'' tab (next to ''Real-Time Info'' tab) and click on ''Reset To Current Orientation'' button
##Now your friend can set the pendulum down and you can zero ERIS the same way.
#Save the new trackable orientation by going to ''File->Save Trackables...'' and save a file using the same naming conventions as the trackable file you opened earlier. Use the current data so you don't have to re-zero the system the next time you test.
[[Image:Uav_ResetOrientation.PNG|800px]]
=== Building Software ===
The development environment for running RADA is hosted on CO3050-11, a Linux Red Hat environment. This computer has a local ucart user name that you should use (the password isn't put here for security reasons). First, ensure that the RADA software is setup correctly for the test you want to run. To do this, you will need to open the main.cpp and logger.cpp files and make sure all of the compile time macros you want are defined correctly. All of the c++ files you should need to edit are in the directory ''~/Desktop/rada_research_project/ErisResearchCode/CppProjects/MainProgram_PacketLoss/src/Korebot'' Below are compiler macro options for main.cpp:
-'''H2ctrl''' : This will cause the system to enter H2 controller mode where the whole RADA system is controlled by an H2 controller.
-'''ssTracking''' : H2ctrl must also be defined for this macro to do anything. This macro will has the system to be controlled by a tracking H2 controller.
-'''ssMotors''' : H2ctrl must also be defined for this macro to do anything. This macro will has the system to be controlled by an H2 contorller that contains propeller states. This also causes the system to "Dance."
-'''ssDrop''' : Cause the system to go into packet drop controller mode. This mode allows controllers designed for lossy networks to be tested. Based off of other definitions how lossy the network is can be simulated. If nothing else is defined this controller becomes basically a H2 controller.
-'''drop10''' : Will put the packet drop mode into 10% loss mode and use a controller designed for 10% loss.
-'''drop30''' : Will put the packet drop mode into 30% loss mode and use a controller designed for 30% loss.
-'''drop50''' : Will put the packet drop mode into 50% loss mode and use a controller designed for 50% loss.
-'''mot50''' : This macro over-rides all other macros. If this is turned on the wheels will not run and the propellers will be run at 50% command. This is used for measuring the effective battery voltage seen by the ESCs. This is always run after a test.
-'''RADAlqi''' : This macro will cause the system to use an LQI controller on the whole system. The linear velocity states are calculated with no filter and the angular velocity states are calculated with filters.
-'''RADAlqi_est''' : This macro will cause the system to use an LQI controller on the whole system. A traditional estimator is used to estimate the states.
-'''rada_lqg''' : This macro will cause the entire system to be controlled by an LQG controller/estimator system.
-'''rada_split_lqg''' : This macro will cause the pendulum and ground robot to be controlled by their own LQG systems.
-'''rada_split_lqg_ol''' : This macro will cause the pendulum to be controlled by an LQG controller, the yaw of the ground robot to be controlled by a PID controller, and the ground robot linear velocities to be controlled with open-loop commands.
-'''yaw_off''' : This macro will cause the yaw control to be disabled on some controllers.
*'''accR''' : This macro will cause the PID linear velocity controllers to be given ramps to accelerate from one velocity to another instead of steps.
-'''posRamp''' : This macro will cause the linear velocities of RADA to be controlled by position PIDs with ramp reference instead of velocity commands.
-If no controller selection is made all controllers revert to PID controllers
All of these macros can be defined simply by uncommenting the corresponding define statement in main.cpp. The macros in the logger.cpp can be seen below:
-'''ssDrop''' : This macro puts the logger into packet drop controller mode and logs the correct values for the packet drop controllers.
-'''RADAlqi''' : This macro puts the logger into full system LQI controller logging mode.
-'''RADAlqi_est''' : This macro puts the logger into full system LQI controller plus estimator logging mode.
-'''rada_lqg''' : This puts the logger into full system LQG controller logging mode.
-'''rada_split_lqg''' : This macro causes the logger to log data about the subsystem LQG controllers.
-'''rada_split_lqg_ol''' : This cause the system to log data about the pendulum LQG system and the open-loop linear velocity commands.
-'''H2ctrl''' : This macro causes the logger to log data about the full system H2 controllers.
-If no logging mode is selected then the logger will default to logging PID data.
Because the system only calculates controllers for one set of controllers it is important to ensure that the logger is in the correct mode based off of what is defined in main.cpp. As of August 1st, 2016 the defines in main.cpp are not seen in logger.cpp.
Finally in a command prompt navigate to the driectroy: ''~/Desktop/rada_research_project/ErisResearchCode/CppProjects/MainProgram_PacketLoss''
Here just type: ''make''. The code will compile for your desired mode. For setting up a new development directory see [http://wikis.ece.iastate.edu/robotic-agriculture-data-acquisition/index.php/Setting_up_a_new_development_environment Setting up a new development environment] from the RADA Senior Design wiki.
[[Image:ComplingRADACode.png|800px]]
The complied executable code ends up in ''/home/shared/MainProject''. The ''/home/shared'' directory is setup as a network file share (NFS).
[[Image:ErisCompliedCode-config.png|800px]]
This service needs to be restarted when CO3050-11 is restarted. [http://wikis.ece.iastate.edu/robotic-agriculture-data-acquisition/index.php/Configuring_NFS_shares_for_the_robot Configure NFS shares for the robot] from the RADA Senior Design wiki. Be sure to use the new Linux install command in step six. Though I have found that even on a good strt the ''[ok]'' messages will still print.
=== Turning on RADA ===
Turning on Eris is fairly simple. Each system has its own battery. There is one for the wheels that plugs in at the front of Eris (opposite side of the switches), one for the electronics in the back of Eris (in between the switches), and one for the propellers that goes on top of Eris.
[[Image:ErisOnPhoto.jpg|800px]]
The wheel battery is normally 1600 mAh 2-cell Lipo but any 2-cell Lipo will work. The wheels are turned on by flipping the silver switch so the top points away from the system. The electronics normally use a 2600 mAh 2-cell Lipo. The electronics are turned on by flipping the green switch away from the system. It is important that you use EITHER the WIFI adapter OR hardwired Ethernet, because the VRPN may listen to the camera data broadcast over both connections which could cause problems. The propeller system is powered via a 2600 mAh 4-cell Lipo that connects to a power cable at the base of the pendulum. There is a switch to turn on the power to the propellers system. You will know it is on when the 1 on the switch is flush with the switch housing instead of sticking out. It takes about 30 seconds to a minute for Eris to boot up and start the networking connections. When the WIFI is plugged in, you will know it is ready when a blue light turns on, on the module.
=== Connecting to RADA ===
RADA is controlled through an SSH connection in a command prompt. This is not the one you compile the code from so that you can recompile for different setup without needing to close the connection. If you are using a WIFI connection, use the command ''ssh root@192.168.0.53''. If you are connected to Eris through a LAN connection use the command ''ssh root@192.168.0.54''. If the connection goes though you should be prompted for a password.
The password is ''rootme''.
[[Image:Ssh2Eris.png|800px]]
It is important to close the SSH connection before turning off Eris because the terminal you are using will hang up if you don't. You can close the connection by using the command ''exit''.
[[Image:ClosingSSH.png|800px]]
== Testing RADA ==
Now that you are connected to Eris you can run tests. The testing is started by a few different methods.
=== Running the First Test After Power Up ===
For the first test after powering on Eris, a few additional steps need to be completed in order to test the system. The FPGA motor controller needs to be programmed and Eris needs to connect to the NFS server running on CO3050-11. This is accomplished by running ''1_co3050-11.sh'', this shell script will setup the NFS, and load the bit file into the FPGA configuration memory. Then it retrieves the executable file from the NFS server ''/mnt/nfs/MainProject'' and runs the executable. Once the user exits the executable, the log file produced is copied from the ''~/Logs/YYYY_MM_DD_Day'' directory on Eris to ''/home/shared/MainProject/Logs/YYYY_MM_DD_Day'' on CO3050-11. When the folder for the current Eris date doesn't exist, it creates this directory in CO3050-11 and then removes the directory and log file from Eris. You may see a warning that when copying the log file Eris couldn't maintain the file permission settings. This is normal as Eris doesn't have the same access to the NSF server as it has to its own files. This date stamp uses the date on Eris, which is currently in June of 2008 as of August 2nd, 2016.
Before starting the test, it is best to have someone spotting the pendulum and holding it near vertical so that the pendulum doesn't have issues when entering a control mode.'''<span style="color:red"> Always ensure the pendulum is spotted by a second person when testing so you don't hurt yourself, others in the lab, or the RADA system.</span>''' Once the spotter is ready, run the shell script by using the command ''./1_co3050-11.sh'' in the terminal with the open SSH connection to Eris from the home, ''/root'', directory of Eris. When you run this script there will be a bunch of information printed out about the PIC bus and loading the bit file to configure the FPGA. You will know that RADA is ready for the test when it asks you to select a running mode. See the Testing Modes section below. This script can take a while to complete so beyond the first test after startup you don't need to run this script. See the Section about Running additional tests below.r
[[Image:StartingRADA initial.png|800px]]
=== Testing Modes ===
The RADA system has three testing modes: Robot Control Mode, Tuning Mode, and Box Step Mode. Additionally, you can exit the execution at any time by pressing the ''Esc'' key. Once the terminal asks you to chose a mode, you can use the following commands to enter the desired mode with a three-second delay or exit the program. You can also use these commands to switch between the modes.
-''v'' : Enters the pendulum PID tuning mode - this will only really work when using PIDs to control the pendulum.
-''b'' : Enter robot control mode - in this mode you can drive the robot around and the pendulum will try to stay vertical. This is the main mode used for testing the whole RADA system.
-''n'' : Enters box step mode - the pendulum will change its desired pitch and roll angles every 20 seconds and move in a box shape.
-''Esc'' : By hitting the escape key the program will exit the program.
You will almost always want to run Robot Control Mode as the other modes are legacy modes from when we initially built and tested RADA and only works with the pendulum PID controllers. There are also a few utility commands that can be used in all modes.
-''2'' : Resets I composts of the Pitch/Roll PIDs and only the PIDs.
-''m'' : Adds a marker to the Log file in case odd things happen somewhere. This just increments a counter, so if you use it, look for changes in the marker value.
==== Robot Control Mode ====
In Robot control mode you can control the motion of Eris. For PID control of Eris or 1D state feedback system the directional commands command Eris body velocity were for full system and Eris system state feedback controllers control the global velocity. All of these keys only need to be pressed not held down.
-''w'' : Moves Eris forward (+x) at some velocity depending on the controller.
-''s'' : Moves Eris in reverse (-x) at some velocity depending on the controller.
-''d'' : Moves Eris in right (+y) at some velocity depending on the controller.
-''a'' : Moves Eris in left (-y) at some velocity depending on the controller.
-''p'' : Stops the motion of Eris (Set all velocity set points to zero). I.e. if you hit ''w'' then hit ''s'' then Eris will be moving in reverse.
-''y'' : Moves Eris forward and to the right (+x/+y) simultaneously at some velocity depending on the controller.
-''t'' : Moves Eris forward and to the left (+x/-y) simultaneously at some velocity depending on the controller.
-''i'' : Moves Eris reverse and to the right (-x/+y) simultaneously at some velocity depending on the controller.
-''y'' : Moves Eris reverse and to the left (-x/-y) simultaneously at some velocity depending on the controller.
-''e'' : Rotate Eris clockwise (+yaw) at some angular rate. This only worked when RADA used the closed-loop FPGA control of the wheels. There is currently no controllers that use this command.
-''q'' : Rotate Eris counter-clockwise (-yaw) at some angular rate. This only worked when RADA used the closed-loop FPGA control of the wheels. There is currently no controllers that use this command.
-''<'' : Increment Eris' desired heading 45 degrees counter-clockwise (-yaw).
-''>'' : Increment Eris' desired heading 45 degrees clockwise (+yaw).
-''7'' : Increments the pitch set point (+pitch).
-''4'' : Decrements the pitch set point (-pitch).
-''8'' : Increments the roll set point (+roll).
-''5'' : Decrements the roll set point (-roll).
==== Tuning Mode ====
Tuning mode allows you to tune the PID controllers for both pitch and roll. The UI commands here are also available in Box Step Mode.
-''1'' : Tune the Pitch PID.
-''3'' : Tune the Roll PID.
-''7'' : Increase proportional gain of PID being tuned.
-''4'' : Decrease proportional gain of PID being tuned.
-''8'' : Increase integral gain of PID being tuned.
-''5'' : Decrease integral gain of PID being tuned.
-''9'' : Increase derivative gain of PID being tuned.
-''6'' : Decrease derivative gain of PID being tuned.
-''i'' : Increase set point of PID being tuned.
-''k'' : Decrease set point of PID being tuned.
-''o'' : Increase integral windup term of PID being tuned. (Not used)
-''l'' : Decrease integral windup term of PID being tuned. (Not used)
==== Box Step Mode ====
Box step mode will automatically change the set points of the pendulum every 20 seconds. The case statement for this mode can be changed for 1D and 2D step modes. This mode allows the user to use the same commands as Tuning Mode.
=== Running Additional Tests ===
Once you have run one test with Eris on, it is unnecessary to configure the FPGA or connect to the NFS server again. This is what took much of the time in the initial setup. This is what the script ''3_start_eris.sh'' was developed for. It does everything that ''1_co3050-11.sh'' does but without reprogramming the FPGA or reconnecting to the NFS server. As a result, it is ready to test much quicker.
Before starting the test, it is best to have someone spotting the pendulum and holding it near vertical so that the pendulum doesn't have issues when entering a control mode.'''<span style="color:red"> Always ensure the pendulum is spotted by a second person when testing so you don't hurt yourself, others in the lab, or the RADA system.</span>''' Once you spotter is ready run the shell script by using the command ''./3_start_eris.sh'' in the terminal with the open SSH connection to Eris from the home, ''/root'', directory of Eris.
[[Image:StartingRADA2nd.png|800px]]
=== Locating and Retrieving Log Files ===
If you are only demoing the system, there is no need to go beyond this point. Once you are done with a test that you want to compare to the model you should retrieve the log file right away so you don't mix it up with other test. On CO3050-11 go to the dircetory ''/home/shared/MainProject/Logs'' using the file browser (you can do this in a terminal but it is easier from the file explorer). Once there, look for the folder that has been modified most recently as Eris date is normally out of sync with its date and time. Then look for the newest log file. Log files have the naming scheme ''log(hh.mm.ss).txt'' (ex. log(13.04.51).txt). This naming convention works well to ensure that no log file is over written but it isn't useful for describing what the test was conducted for. Copy this log to the Desktop or to a USB drive and rename it. A good method is to name the file something like ''RADA_ctrl_otherNote#.txt'', where Describes what system you tested (ex. RADA, RADA1D, PEN1D, PEN2D), what typ of controller was used, other notes and then a number if this is a repeat of another test. This is much more useful when looking back at these logs later on. Before transferring the log file for processing you should record the wheel and propeller battery voltages in the header of the log file. The log file format is both human readable and can be parsed by MATALB. It was designed by the first RADA Senior Design Team and more information about the log files can be found [http://wikis.ece.iastate.edu/robotic-agriculture-data-acquisition/index.php/Data_Analysis_Tool here.] See he section below on measuring battery voltage below in order to get the best measurements for simulation of RADA.
=== Measuring Battery Voltages ===
The last thing that you need to do before simulating an experiment of the RADA platform is record the battery voltages for both the wheels and propellers. The wheel battery can be measured unloaded as there aren't large line losses between the battery and the H-bridges. The propeller battery voltage needs to be measured under load because the power cord running up the pendulum has significant line losses at the currents the propellers draw when in use. The battery voltages can be recorded in the log file for the test. Open the log file for the test you just completed (Use KWrite for Linux machines or Notepad++ for Windows machines). The first few lines of the log are the header. It should look like this:
#Constants pitch_P pitch_I pitch_D
#PIDValues 48000 18000 21000
#Constants roll_P roll_I roll_D
#PIDValues 48000 18000 21000
#Battery Vquad Vwheels
#Voltage
Follow the procedure for measuring the voltage of each battery and then record the voltage under the corresponding battery. Then save the log file and close out of your text editor and the test will be ready for processing. Recoding the battery voltages in this way makes it much easier to find if you need the value later. The final log file header should look like this once you are done
#Constants pitch_P pitch_I pitch_D
#PIDValues 48000 18000 21000
#Constants roll_P roll_I roll_D
#PIDValues 48000 18000 21000
#Battery Vquad Vwheels
#Voltage 14.44 8.257
==== Wheel Battery ====
#After test disconnect wheel battery from the system.
#Measure voltage of battery using multimeter.
[[Image:MeasureVwheel.jpg|800px]]
You can use the plug used for charging the 2-cell Lipos but make sure to connect the plug to the multimeter before connecting the battery and disconnect the battery before disconnecting the plug from the mulitmeter. It is generally the best practice to give the multimeter a few minutes to allow for the voltage measurement to stabilize as the battery measurement tends to be a little low right after the test. The multimeter will report data out to four decimal places it is best just to round to three decimal places for the wheel voltage.
==== Propeller Battery ====
#Setup code to run all four propellers at 50% throttle, uncomment the definition of ''mot50'' in main.cpp and compile the project.
#Power off propellers by turning off the switch to the ESCs.
#Connect multimeter to measure the voltage across one of the ESCs. This is done by using the power splitter cord.
##Connect one of the female XT60 connectors on the splitter to a male XT60 connector to banana connector cable.
##The banana connector connects to the hand held multimeter. The multimeter should be set to the 20VDC measurement setting.
##Next unplug one the ESCs' power connection.
##Reconnect the ESC to power through the two remain connectors on the splitter cable.
#Power on the propellers.
#Run the system at 50% throttle and measure the steady-state voltage during the test. The battery will slow the voltage decay significantly, meaning it will keep the same measurement for a few seconds.
#Stop the test and record the voltage in the log file. Make sure to disconnect the battery before removing the splitter cable.
{| class="wikitable" style="text-align:center"
|-
| [[Image:PowerSplitter.jpg|200px]]
| [[Image:QuadMultiCon.jpg |200px]]
| [[Image:QuadMultiSet.JPG |200px]]
| [[Image:QuadMeasESCcon.JPG|200px]]
|-
| Splitter cord.
| Connect splitter to multimeter.
| Settings for multimeter.
| Connecting ESC through splitter.
|}
The testing setup should look like the image below:
[[Image:QuadBattMeas.jpg|800px]]
== Post processing and Simulation ==
Simulating a test of RADA starts with processing and storing the data. Then all of the parameters of the model are loaded in the MATLAB Workspace. Finally the Simulink file used for the simulation is opened and the length of the simulation is set to match the length of the actual test. The simulation is run and the simulation output is stored. Finally the data should be plotted and compared.
=== Using the MATLAB data parsing tool ===
In depth discussion of how to use the log file parsing tool is described [http://wikis.ece.iastate.edu/robotic-agriculture-data-acquisition/index.php/Data_Analysis_Tool here.] I suggest using the version of the tool in the rada_resarch_project git repository Paul Uhing used for his Master's research. It con be found on CO3050-11 under the ucart account in the directory ''~/rada_research_project/DataAnalysiTool_omnicoor/Tool''. Simply open MATLAB and set the working directory to this file path. In the MATLAB Command Prompt run ''DataAnalysis''. A popup window should open up. Select the log file you want to process and wait for the tool to finish processing the file. Once this is complete there should be four structures in the MATLAB workspace.
-'''main''' : This contains all of the data extracted from the log file and the processing parameters used. main.expData contains two time structures: Time is used for the pendulum data and Eris_time is used for the ground vehicle data.
-'''X_ref''' : This contains the reference vector in m/s for x velocity that is feed into Simulink. This expedites the simulation setup process, this used to be done by hand.
-'''Y_ref''' : This contains the reference vector in m/s for y velocity that is feed into Simulink. This expedites the simulation setup process, this used to be done by hand.
-'''Yaw_ref''' : This contains the reference vector in radians for yaw that is feed into Simulink. This expedites the simulation setup process, this used to be done by hand. This one is new incase people start testing the system with heading changes but is not used in the current setup.
The first thing you should do is rename the main structure to the name you used for the log file. This is helpful for comparing multiple tests. Next you will want to crate two new variable ''Vquad_test'' an Vw_test''. In the MATLAB Command Prompt set the measured propeller voltage from the log file to ''Vquad_test'' and set the measured the wheel voltage to ''Vw_test'' as this will be used by the simulation. Finally if you did an open-loop test of the wheels create the variable ''Uol'' and set it to the open-loop wheel command used. Save all of these variables from the MATLAB workspace to a ''.mat'' file of the same name as log file you extracted the data from and save it in the same directory as your RADA Simulink files. As of August 2nd, 2016 this directory is ''~/rada_research_project/MATLAB/RADA.''
=== Setting up the MATLAB workspace for simulation ===
Change your MATLAB directory to this directory. Then run the simulation setup files. Currently you just need to run ''modelParams_smallWheels_RADA'' in the MATLAB Command Prompt. Next open the Simulink file with that contains the model of RADA controlled by the controller you tested.
-'''RADA_psiCtrl_v2_lqi_est.slx''' contains LQI, LQI+estimation, and LQG controller simulations.
-'''RADA_psiCtrl_v2.slx''' contains the PID controlled system.
-'''RADA_psiCtrl_v2_LQGsep.slx''' contains the subsystem LQG controlled system.
-'''RADA_psiCtrl_v2_LQGsep_ol.slx''' contains the simulation of the pendulum system controlled by an LQG and Eris controlled with open-loop commands.
Note all of the current (August 2nd, 2016) ''.slx'' files were created in MATLAB 2014b and will only work in MATLAB 2014B or newer. Then in the MATLAB Command Prompt type ''X_ref.time(end)'' exactly, don't add a semicolon, and hit enter. MATLAB will print the time of the last command in the X_ref structure. Set the en time of the simulation to this value and save your Simulink file.
=== Running simulations and storing results ===
Before running the simulation make sure that the simuation is using the ''ode23t'' differential equations solver. This system is a moderately stiff system of differential and the ''ode45'' solver doesn't do well with these types of systems. When using ''ode23t'' is should only take a few minutes to run a 100+ second simulation while doing the same test using ''ode45'' could take 8 hours. While this slow it is also bad for your hard drive as the simulation has to page between RAM and your computers hard drive a lot.
Once this check is done run the simulation. While it is running check what the output structures variables are named for for your RADA test system. Once the simulation is done go to your MATLAB Workspace and select all 15 outputs for your simulation or your sub-simulation if you used '''RADA_psiCtrl_v2_lqi_est.slx'''. Save these 15 output structures to a ''.mat'' file named as the log file with _sim appended to the end of the name.
The 15 outputs are structures containing a time vector and then the data from the simulation sampled at 100 Hz and the units of this data are the SI units (ex: radians, m/s). There is one output structure for x velocity, y velocity, x body velocity, y body velocity, theta (pitch), phi (roll), psi (yaw), and one per actuator command (ex: the command sent to a wheel). Now you have all the data you can plot it.
=== Plotting results ===
If you look at the ''DataSets'' folder below ''~/rada_research_project/MATLAB/RADA'' directory there are plenty of examples of how Paul Uhing compared simulation to test data. Generally you should grate a ''.m'' file with the same name as the log file this data was extracted from with _plot appended to the name.
Generally you can just copy an for RADA_LQG_compPID_plot.m RADA_PID_compLQG_plot.m, RADA_LQG_sep_plot.m, or RADA_LQG_sep_ol_plot.m files and rename the structures for your test.
These files create four figures. Figure 1 plots compares the x velocity data in the first sub figure and compares pitch (theta) data in the second sub figure. Figure 2 does the same thing as Figure 1 but with y velocity and roll data. Figure 3 looks at the yaw data. Finally, Figure 4 looks at the sample period between UAV and ERIS packets from the camera system just to check for periods of time with large packet drops.
You can follow a similar pattern to compare motor commands. Just make sure that you compare Quad Motor 2 from the test data with Quad Motor 4 from simulation and vise versa because propellers 2 and 4 were switch in Eris's software compared to the Model.
That is all you need to know for testing RADA against the model.
9a5391308e212c9f324dafa2b6f7c87881ffeb52
341
340
2016-09-22T00:05:12Z
Jonessk
7
/* Post processing and Simulation */
wikitext
text/x-wiki
This page will take you though setting up and testing RADA, retrieving the log file and other necessary data to run a simulation of that test and processing the data in MATLAB. Then actually running the simulation of RADA in Simulink. The initial setup and how to test the system can also be applied to demoing RADA.
== Setting Up a RADA Test ==
Testing RADA is not overly difficult once you get the hang of the steps to setup RADA. The following steps may seem like a long process to go from starting the testing process to having completed simulation and plotting of the test results but this whole test procedure (with the exception of battery charging) can be completed in about 15-20 minutes. These steps are meant to be as detailed as possible in order to help new users of RADA get up and running as quickly as possible.
'''<span style="color:red">NOTE: Always run RADA with at least 2 people!</span>''' The pendulum arm can crash into the ground if the network starts to drop packets and one person cannot give commands to RADA and spot the pendulum. This is a safety issue for both you and the RADA platform.
=== Charging Batteries ===
The lab currently uses mostly Hyperion batteries. We charge our batteries with a Hyperion EOS 1420i Net3 battery charger. For some general information about how to use this charger see [https://www.youtube.com/watch?v=-ox3EpzvsJ8 this video.]. In the lab we power this charger using the old Kepco Power supply because it is the only power supply that can supply enough current. Make sure that the power supply is set to an output voltage between 10.5V-29V.
{| class="wikitable" style="text-align:center"
|-
| [[Image:ChargerPowerSupplyOff.JPG|400px]]
| [[Image:ChargerPowerSuplyOn.JPG|400px]]
|-
| Kepco Power Supply off.
| Kepco Power Supply on with correct voltage supply range.
|}
The YouTube video link above should explain how to use the charger. RADA currently uses three different Lithium polymer (Lipo) batteries: 1600 mAh 2-cell Lipo for the wheels, 2600 mAh 2-cell Lipo for the electronics of Eris, and a 2600 mAh 4-cell Lipo for the propellers. The 1600 mAh 2-cell Lipo can be charged using memory slot 2 of the charger. The 2600 mAh 2-cell Lipos can be charged using memory slot 3 for fast charging and memory slot 4 for slower charging (use this if the battery voltage drops really low for 10-20 minutes then switch to fast charging). The 2600 mAh 4-cell Lipo can be charged using memory slot 8. The 1600 mAh 2-cell and 2600 mAh 4-cell generally charge in 10-20 minutes apiece while the 2600 mAh 2-cell generally take up to 70 minutes to charge fully.
=== Setting up the Camera System ===
The camera system is run on the windows computer CO3050-07. You can log into this computer using a local microcart username and password (not posted here for security reasons, but any one who works in the lab should know it). Once logged in, look for Tracking Tools in the start menu or look for the shortcut shown below:
[[Image:TrackingTools_shortcut.PNG|thumb|center|Tracking Tools shortcut]]
Once the program opens the screen should look something like this:
[[Image:NewTrackingTools.PNG|800px]]
In the Tracking Tools Quick Start pop up menu select Open Existing Project and then navigate to ''D:\Optitrack_Configuration'' (It should open to this directory by default) and select the most recent Tracking Tools project. It should have the naming scheme ''TrackingToolsProject YYYY-MM-DD timeStamp.ttp''. This is normally the most recently edited file when sorting by date modified. The most recent one as of August 1st, 2016 is ''TrackingToolsProject 2015-09-23 2.30pm.ttp''.
[[Image:OpeningProject.PNG|800px]]
You should notice that the cameras shown in the main project screen arrange themselves like the camera system configuration once the project has been opened. Now the constellations need to be loaded. This can be done by going to ''File->Open'' and another popup window will open. Navigate back to ''D:\Optitrack_Configuration'' (It should open to this directory by default) and select the most recently dated set of RADA trackables. They have the naming scheme ''RADA_entireSystem_M_D_YYYY.tra''. The most recent one as of August 1st, 2016 is ''RADA_entireSystem_7_8_2016.tra''.
[[Image:Opening_trackables.PNG|800px]]
Once the project and trackables are open, the cameras should appear in their constellation (square) and there should be two constellations under ''Project Explorer->Trackables''. One named UAV for the pendulum and one named ERIS for the ground vehicle. In order to get additional information about each constellation, left click on the the name of the desired trackable.
[[Image:SelectingUAV.PNG|800px]]
Once a trackable is selected more information about it is available in the ''Trackables'' Tab on the right side of the screen. For the current position and orientation look at the ''Real-Time Info'' sub-tab. This gives the orientation in the wrong order for how we currently use the Euler angles. When two or three of the angles are near zero you can switch yaw and pitch to get roughly the correct orientation.
[[Image:Uav_realTimeInfo.PNG|800px]]
Now we need to check to make sure the system is zeroed.
#Hold RADA so that the front of the ground robot (ERIS is facing the wall with the white boards (east)). The front side of Eris is labeled. If it isn't, the front is the side opposite the switches and the side with the trackable constellation on it.
#Make sure that the motor with the red motor mount is also facing the wall with the white boards.
#Make sure the quad system is aligned along Eris Axis by standing behind the system. If the system is aligned, you should be able to block the mounting bolts of the front propeller motor with the pole while facing the east wall.
#While holding the pendulum approximately vertical, see if the camera system reads zeros for the pendulum (UAV) pitch and roll (yaw and roll in ''Real-Time Info''). If yaw is off by a few degrees that is fine.
#Compare the yaw of the UAV to that of ERIS (Remember this is pitch in ''Real-Time Info''). If they are both near zero and within a few degrees and the pendulum's pitch/roll were also near zero then you are ready to use the camera system. Otherwise, go to the next step.
#You need to zero the pendulum.
##Align ERIS so it is near zero yaw first (eye ball it).
##Get a level and a friend. Have your friend use a level to ensure that the pendulum is level in both directions and hold it there.
##With the UAV constellation selected go to the ''Orientation'' tab (next to ''Real-Time Info'' tab) and click on ''Reset To Current Orientation'' button
##Now your friend can set the pendulum down and you can zero ERIS the same way.
#Save the new trackable orientation by going to ''File->Save Trackables...'' and save a file using the same naming conventions as the trackable file you opened earlier. Use the current data so you don't have to re-zero the system the next time you test.
[[Image:Uav_ResetOrientation.PNG|800px]]
=== Building Software ===
The development environment for running RADA is hosted on CO3050-11, a Linux Red Hat environment. This computer has a local ucart user name that you should use (the password isn't put here for security reasons). First, ensure that the RADA software is setup correctly for the test you want to run. To do this, you will need to open the main.cpp and logger.cpp files and make sure all of the compile time macros you want are defined correctly. All of the c++ files you should need to edit are in the directory ''~/Desktop/rada_research_project/ErisResearchCode/CppProjects/MainProgram_PacketLoss/src/Korebot'' Below are compiler macro options for main.cpp:
-'''H2ctrl''' : This will cause the system to enter H2 controller mode where the whole RADA system is controlled by an H2 controller.
-'''ssTracking''' : H2ctrl must also be defined for this macro to do anything. This macro will has the system to be controlled by a tracking H2 controller.
-'''ssMotors''' : H2ctrl must also be defined for this macro to do anything. This macro will has the system to be controlled by an H2 contorller that contains propeller states. This also causes the system to "Dance."
-'''ssDrop''' : Cause the system to go into packet drop controller mode. This mode allows controllers designed for lossy networks to be tested. Based off of other definitions how lossy the network is can be simulated. If nothing else is defined this controller becomes basically a H2 controller.
-'''drop10''' : Will put the packet drop mode into 10% loss mode and use a controller designed for 10% loss.
-'''drop30''' : Will put the packet drop mode into 30% loss mode and use a controller designed for 30% loss.
-'''drop50''' : Will put the packet drop mode into 50% loss mode and use a controller designed for 50% loss.
-'''mot50''' : This macro over-rides all other macros. If this is turned on the wheels will not run and the propellers will be run at 50% command. This is used for measuring the effective battery voltage seen by the ESCs. This is always run after a test.
-'''RADAlqi''' : This macro will cause the system to use an LQI controller on the whole system. The linear velocity states are calculated with no filter and the angular velocity states are calculated with filters.
-'''RADAlqi_est''' : This macro will cause the system to use an LQI controller on the whole system. A traditional estimator is used to estimate the states.
-'''rada_lqg''' : This macro will cause the entire system to be controlled by an LQG controller/estimator system.
-'''rada_split_lqg''' : This macro will cause the pendulum and ground robot to be controlled by their own LQG systems.
-'''rada_split_lqg_ol''' : This macro will cause the pendulum to be controlled by an LQG controller, the yaw of the ground robot to be controlled by a PID controller, and the ground robot linear velocities to be controlled with open-loop commands.
-'''yaw_off''' : This macro will cause the yaw control to be disabled on some controllers.
*'''accR''' : This macro will cause the PID linear velocity controllers to be given ramps to accelerate from one velocity to another instead of steps.
-'''posRamp''' : This macro will cause the linear velocities of RADA to be controlled by position PIDs with ramp reference instead of velocity commands.
-If no controller selection is made all controllers revert to PID controllers
All of these macros can be defined simply by uncommenting the corresponding define statement in main.cpp. The macros in the logger.cpp can be seen below:
-'''ssDrop''' : This macro puts the logger into packet drop controller mode and logs the correct values for the packet drop controllers.
-'''RADAlqi''' : This macro puts the logger into full system LQI controller logging mode.
-'''RADAlqi_est''' : This macro puts the logger into full system LQI controller plus estimator logging mode.
-'''rada_lqg''' : This puts the logger into full system LQG controller logging mode.
-'''rada_split_lqg''' : This macro causes the logger to log data about the subsystem LQG controllers.
-'''rada_split_lqg_ol''' : This cause the system to log data about the pendulum LQG system and the open-loop linear velocity commands.
-'''H2ctrl''' : This macro causes the logger to log data about the full system H2 controllers.
-If no logging mode is selected then the logger will default to logging PID data.
Because the system only calculates controllers for one set of controllers it is important to ensure that the logger is in the correct mode based off of what is defined in main.cpp. As of August 1st, 2016 the defines in main.cpp are not seen in logger.cpp.
Finally in a command prompt navigate to the driectroy: ''~/Desktop/rada_research_project/ErisResearchCode/CppProjects/MainProgram_PacketLoss''
Here just type: ''make''. The code will compile for your desired mode. For setting up a new development directory see [http://wikis.ece.iastate.edu/robotic-agriculture-data-acquisition/index.php/Setting_up_a_new_development_environment Setting up a new development environment] from the RADA Senior Design wiki.
[[Image:ComplingRADACode.png|800px]]
The complied executable code ends up in ''/home/shared/MainProject''. The ''/home/shared'' directory is setup as a network file share (NFS).
[[Image:ErisCompliedCode-config.png|800px]]
This service needs to be restarted when CO3050-11 is restarted. [http://wikis.ece.iastate.edu/robotic-agriculture-data-acquisition/index.php/Configuring_NFS_shares_for_the_robot Configure NFS shares for the robot] from the RADA Senior Design wiki. Be sure to use the new Linux install command in step six. Though I have found that even on a good strt the ''[ok]'' messages will still print.
=== Turning on RADA ===
Turning on Eris is fairly simple. Each system has its own battery. There is one for the wheels that plugs in at the front of Eris (opposite side of the switches), one for the electronics in the back of Eris (in between the switches), and one for the propellers that goes on top of Eris.
[[Image:ErisOnPhoto.jpg|800px]]
The wheel battery is normally 1600 mAh 2-cell Lipo but any 2-cell Lipo will work. The wheels are turned on by flipping the silver switch so the top points away from the system. The electronics normally use a 2600 mAh 2-cell Lipo. The electronics are turned on by flipping the green switch away from the system. It is important that you use EITHER the WIFI adapter OR hardwired Ethernet, because the VRPN may listen to the camera data broadcast over both connections which could cause problems. The propeller system is powered via a 2600 mAh 4-cell Lipo that connects to a power cable at the base of the pendulum. There is a switch to turn on the power to the propellers system. You will know it is on when the 1 on the switch is flush with the switch housing instead of sticking out. It takes about 30 seconds to a minute for Eris to boot up and start the networking connections. When the WIFI is plugged in, you will know it is ready when a blue light turns on, on the module.
=== Connecting to RADA ===
RADA is controlled through an SSH connection in a command prompt. This is not the one you compile the code from so that you can recompile for different setup without needing to close the connection. If you are using a WIFI connection, use the command ''ssh root@192.168.0.53''. If you are connected to Eris through a LAN connection use the command ''ssh root@192.168.0.54''. If the connection goes though you should be prompted for a password.
The password is ''rootme''.
[[Image:Ssh2Eris.png|800px]]
It is important to close the SSH connection before turning off Eris because the terminal you are using will hang up if you don't. You can close the connection by using the command ''exit''.
[[Image:ClosingSSH.png|800px]]
== Testing RADA ==
Now that you are connected to Eris you can run tests. The testing is started by a few different methods.
=== Running the First Test After Power Up ===
For the first test after powering on Eris, a few additional steps need to be completed in order to test the system. The FPGA motor controller needs to be programmed and Eris needs to connect to the NFS server running on CO3050-11. This is accomplished by running ''1_co3050-11.sh'', this shell script will setup the NFS, and load the bit file into the FPGA configuration memory. Then it retrieves the executable file from the NFS server ''/mnt/nfs/MainProject'' and runs the executable. Once the user exits the executable, the log file produced is copied from the ''~/Logs/YYYY_MM_DD_Day'' directory on Eris to ''/home/shared/MainProject/Logs/YYYY_MM_DD_Day'' on CO3050-11. When the folder for the current Eris date doesn't exist, it creates this directory in CO3050-11 and then removes the directory and log file from Eris. You may see a warning that when copying the log file Eris couldn't maintain the file permission settings. This is normal as Eris doesn't have the same access to the NSF server as it has to its own files. This date stamp uses the date on Eris, which is currently in June of 2008 as of August 2nd, 2016.
Before starting the test, it is best to have someone spotting the pendulum and holding it near vertical so that the pendulum doesn't have issues when entering a control mode.'''<span style="color:red"> Always ensure the pendulum is spotted by a second person when testing so you don't hurt yourself, others in the lab, or the RADA system.</span>''' Once the spotter is ready, run the shell script by using the command ''./1_co3050-11.sh'' in the terminal with the open SSH connection to Eris from the home, ''/root'', directory of Eris. When you run this script there will be a bunch of information printed out about the PIC bus and loading the bit file to configure the FPGA. You will know that RADA is ready for the test when it asks you to select a running mode. See the Testing Modes section below. This script can take a while to complete so beyond the first test after startup you don't need to run this script. See the Section about Running additional tests below.r
[[Image:StartingRADA initial.png|800px]]
=== Testing Modes ===
The RADA system has three testing modes: Robot Control Mode, Tuning Mode, and Box Step Mode. Additionally, you can exit the execution at any time by pressing the ''Esc'' key. Once the terminal asks you to chose a mode, you can use the following commands to enter the desired mode with a three-second delay or exit the program. You can also use these commands to switch between the modes.
-''v'' : Enters the pendulum PID tuning mode - this will only really work when using PIDs to control the pendulum.
-''b'' : Enter robot control mode - in this mode you can drive the robot around and the pendulum will try to stay vertical. This is the main mode used for testing the whole RADA system.
-''n'' : Enters box step mode - the pendulum will change its desired pitch and roll angles every 20 seconds and move in a box shape.
-''Esc'' : By hitting the escape key the program will exit the program.
You will almost always want to run Robot Control Mode as the other modes are legacy modes from when we initially built and tested RADA and only works with the pendulum PID controllers. There are also a few utility commands that can be used in all modes.
-''2'' : Resets I composts of the Pitch/Roll PIDs and only the PIDs.
-''m'' : Adds a marker to the Log file in case odd things happen somewhere. This just increments a counter, so if you use it, look for changes in the marker value.
==== Robot Control Mode ====
In Robot control mode you can control the motion of Eris. For PID control of Eris or 1D state feedback system the directional commands command Eris body velocity were for full system and Eris system state feedback controllers control the global velocity. All of these keys only need to be pressed not held down.
-''w'' : Moves Eris forward (+x) at some velocity depending on the controller.
-''s'' : Moves Eris in reverse (-x) at some velocity depending on the controller.
-''d'' : Moves Eris in right (+y) at some velocity depending on the controller.
-''a'' : Moves Eris in left (-y) at some velocity depending on the controller.
-''p'' : Stops the motion of Eris (Set all velocity set points to zero). I.e. if you hit ''w'' then hit ''s'' then Eris will be moving in reverse.
-''y'' : Moves Eris forward and to the right (+x/+y) simultaneously at some velocity depending on the controller.
-''t'' : Moves Eris forward and to the left (+x/-y) simultaneously at some velocity depending on the controller.
-''i'' : Moves Eris reverse and to the right (-x/+y) simultaneously at some velocity depending on the controller.
-''y'' : Moves Eris reverse and to the left (-x/-y) simultaneously at some velocity depending on the controller.
-''e'' : Rotate Eris clockwise (+yaw) at some angular rate. This only worked when RADA used the closed-loop FPGA control of the wheels. There is currently no controllers that use this command.
-''q'' : Rotate Eris counter-clockwise (-yaw) at some angular rate. This only worked when RADA used the closed-loop FPGA control of the wheels. There is currently no controllers that use this command.
-''<'' : Increment Eris' desired heading 45 degrees counter-clockwise (-yaw).
-''>'' : Increment Eris' desired heading 45 degrees clockwise (+yaw).
-''7'' : Increments the pitch set point (+pitch).
-''4'' : Decrements the pitch set point (-pitch).
-''8'' : Increments the roll set point (+roll).
-''5'' : Decrements the roll set point (-roll).
==== Tuning Mode ====
Tuning mode allows you to tune the PID controllers for both pitch and roll. The UI commands here are also available in Box Step Mode.
-''1'' : Tune the Pitch PID.
-''3'' : Tune the Roll PID.
-''7'' : Increase proportional gain of PID being tuned.
-''4'' : Decrease proportional gain of PID being tuned.
-''8'' : Increase integral gain of PID being tuned.
-''5'' : Decrease integral gain of PID being tuned.
-''9'' : Increase derivative gain of PID being tuned.
-''6'' : Decrease derivative gain of PID being tuned.
-''i'' : Increase set point of PID being tuned.
-''k'' : Decrease set point of PID being tuned.
-''o'' : Increase integral windup term of PID being tuned. (Not used)
-''l'' : Decrease integral windup term of PID being tuned. (Not used)
==== Box Step Mode ====
Box step mode will automatically change the set points of the pendulum every 20 seconds. The case statement for this mode can be changed for 1D and 2D step modes. This mode allows the user to use the same commands as Tuning Mode.
=== Running Additional Tests ===
Once you have run one test with Eris on, it is unnecessary to configure the FPGA or connect to the NFS server again. This is what took much of the time in the initial setup. This is what the script ''3_start_eris.sh'' was developed for. It does everything that ''1_co3050-11.sh'' does but without reprogramming the FPGA or reconnecting to the NFS server. As a result, it is ready to test much quicker.
Before starting the test, it is best to have someone spotting the pendulum and holding it near vertical so that the pendulum doesn't have issues when entering a control mode.'''<span style="color:red"> Always ensure the pendulum is spotted by a second person when testing so you don't hurt yourself, others in the lab, or the RADA system.</span>''' Once you spotter is ready run the shell script by using the command ''./3_start_eris.sh'' in the terminal with the open SSH connection to Eris from the home, ''/root'', directory of Eris.
[[Image:StartingRADA2nd.png|800px]]
=== Locating and Retrieving Log Files ===
If you are only demoing the system, there is no need to go beyond this point. Once you are done with a test that you want to compare to the model you should retrieve the log file right away so you don't mix it up with other test. On CO3050-11 go to the dircetory ''/home/shared/MainProject/Logs'' using the file browser (you can do this in a terminal but it is easier from the file explorer). Once there, look for the folder that has been modified most recently as Eris date is normally out of sync with its date and time. Then look for the newest log file. Log files have the naming scheme ''log(hh.mm.ss).txt'' (ex. log(13.04.51).txt). This naming convention works well to ensure that no log file is over written but it isn't useful for describing what the test was conducted for. Copy this log to the Desktop or to a USB drive and rename it. A good method is to name the file something like ''RADA_ctrl_otherNote#.txt'', where Describes what system you tested (ex. RADA, RADA1D, PEN1D, PEN2D), what typ of controller was used, other notes and then a number if this is a repeat of another test. This is much more useful when looking back at these logs later on. Before transferring the log file for processing you should record the wheel and propeller battery voltages in the header of the log file. The log file format is both human readable and can be parsed by MATALB. It was designed by the first RADA Senior Design Team and more information about the log files can be found [http://wikis.ece.iastate.edu/robotic-agriculture-data-acquisition/index.php/Data_Analysis_Tool here.] See he section below on measuring battery voltage below in order to get the best measurements for simulation of RADA.
=== Measuring Battery Voltages ===
The last thing that you need to do before simulating an experiment of the RADA platform is record the battery voltages for both the wheels and propellers. The wheel battery can be measured unloaded as there aren't large line losses between the battery and the H-bridges. The propeller battery voltage needs to be measured under load because the power cord running up the pendulum has significant line losses at the currents the propellers draw when in use. The battery voltages can be recorded in the log file for the test. Open the log file for the test you just completed (Use KWrite for Linux machines or Notepad++ for Windows machines). The first few lines of the log are the header. It should look like this:
#Constants pitch_P pitch_I pitch_D
#PIDValues 48000 18000 21000
#Constants roll_P roll_I roll_D
#PIDValues 48000 18000 21000
#Battery Vquad Vwheels
#Voltage
Follow the procedure for measuring the voltage of each battery and then record the voltage under the corresponding battery. Then save the log file and close out of your text editor and the test will be ready for processing. Recoding the battery voltages in this way makes it much easier to find if you need the value later. The final log file header should look like this once you are done
#Constants pitch_P pitch_I pitch_D
#PIDValues 48000 18000 21000
#Constants roll_P roll_I roll_D
#PIDValues 48000 18000 21000
#Battery Vquad Vwheels
#Voltage 14.44 8.257
==== Wheel Battery ====
#After test disconnect wheel battery from the system.
#Measure voltage of battery using multimeter.
[[Image:MeasureVwheel.jpg|800px]]
You can use the plug used for charging the 2-cell Lipos but make sure to connect the plug to the multimeter before connecting the battery and disconnect the battery before disconnecting the plug from the mulitmeter. It is generally the best practice to give the multimeter a few minutes to allow for the voltage measurement to stabilize as the battery measurement tends to be a little low right after the test. The multimeter will report data out to four decimal places it is best just to round to three decimal places for the wheel voltage.
==== Propeller Battery ====
#Setup code to run all four propellers at 50% throttle, uncomment the definition of ''mot50'' in main.cpp and compile the project.
#Power off propellers by turning off the switch to the ESCs.
#Connect multimeter to measure the voltage across one of the ESCs. This is done by using the power splitter cord.
##Connect one of the female XT60 connectors on the splitter to a male XT60 connector to banana connector cable.
##The banana connector connects to the hand held multimeter. The multimeter should be set to the 20VDC measurement setting.
##Next unplug one the ESCs' power connection.
##Reconnect the ESC to power through the two remain connectors on the splitter cable.
#Power on the propellers.
#Run the system at 50% throttle and measure the steady-state voltage during the test. The battery will slow the voltage decay significantly, meaning it will keep the same measurement for a few seconds.
#Stop the test and record the voltage in the log file. Make sure to disconnect the battery before removing the splitter cable.
{| class="wikitable" style="text-align:center"
|-
| [[Image:PowerSplitter.jpg|200px]]
| [[Image:QuadMultiCon.jpg |200px]]
| [[Image:QuadMultiSet.JPG |200px]]
| [[Image:QuadMeasESCcon.JPG|200px]]
|-
| Splitter cord.
| Connect splitter to multimeter.
| Settings for multimeter.
| Connecting ESC through splitter.
|}
The testing setup should look like the image below:
[[Image:QuadBattMeas.jpg|800px]]
== Post Processing and Simulation ==
Simulating a test of RADA starts with processing and storing the data. Then all of the parameters of the model are loaded in the MATLAB Workspace. Next, the Simulink file used for the simulation is opened and the length of the simulation is set to match the length of the actual test. The simulation is run and the simulation output is stored. Finally, the data should be plotted and compared.
=== Using the MATLAB Data Parsing Tool ===
In-depth discussion of how to use the log file parsing tool is described [http://wikis.ece.iastate.edu/robotic-agriculture-data-acquisition/index.php/Data_Analysis_Tool here.] It is suggested to use the version of the tool in the rada_resarch_project git repository Paul Uhing used for his Master's research. It can be found on CO3050-11 under the ucart account in the directory ''~/rada_research_project/DataAnalysiTool_omnicoor/Tool''. Simply open MATLAB and set the working directory to this file path. In the MATLAB Command Prompt run ''DataAnalysis''. A popup window should open up. Select the log file you want to process and wait for the tool to finish processing the file. Once this is complete there should be four structures in the MATLAB workspace.
-'''main''' : This contains all of the data extracted from the log file and the processing parameters used. main.expData contains two time structures: Time is used for the pendulum data and Eris_time is used for the ground vehicle data.
-'''X_ref''' : This contains the reference vector in m/s for x velocity that is fed into Simulink. This expedites the simulation setup process, this used to be done by hand.
-'''Y_ref''' : This contains the reference vector in m/s for y velocity that is fed into Simulink. This expedites the simulation setup process, this used to be done by hand.
-'''Yaw_ref''' : This contains the reference vector in radians for yaw that is fed into Simulink. This expedites the simulation setup process, this used to be done by hand. This one is new in case people start testing the system with heading changes but is not used in the current setup.
The first thing you should do is rename the main structure to the name you used for the log file. This is helpful for comparing multiple tests. Next, you will want to create two new variable ''Vquad_test'' and ''Vw_test''. In the MATLAB Command Prompt set the measured propeller voltage from the log file to ''Vquad_test'' and set the measured wheel voltage to ''Vw_test'' as this will be used by the simulation. Finally, if you did an open-loop test of the wheels create the variable ''Uol'' and set it to the open-loop wheel command used. Save all of these variables from the MATLAB workspace to a ''.mat'' file of the same name as the log file you extracted the data from and save it in the same directory as your RADA Simulink files. As of August 2nd, 2016 this directory is ''~/rada_research_project/MATLAB/RADA.''
=== Setting up the MATLAB Workspace for Simulation ===
Change your MATLAB directory to this directory. Then run the simulation setup files. Currently, you only need to run ''modelParams_smallWheels_RADA'' in the MATLAB Command Prompt. Next, open the Simulink file that contains the model of RADA controlled by the controller you tested.
-'''RADA_psiCtrl_v2_lqi_est.slx''' contains LQI, LQI+estimation, and LQG controller simulations.
-'''RADA_psiCtrl_v2.slx''' contains the PID controlled system.
-'''RADA_psiCtrl_v2_LQGsep.slx''' contains the subsystem LQG controlled system.
-'''RADA_psiCtrl_v2_LQGsep_ol.slx''' contains the simulation of the pendulum system controlled by an LQG and Eris controlled with open-loop commands.
Note all of the current (August 2nd, 2016) ''.slx'' files were created in MATLAB 2014b and will only work in MATLAB 2014b or newer. Then in the MATLAB Command Prompt type ''X_ref.time(end)'' exactly, don't add a semicolon, and hit enter. MATLAB will print the time of the last command in the X_ref structure. Set the end time of the simulation to this value and save your Simulink file.
=== Running Simulations and Storing Results ===
Before running the simulation make sure that the simulation is using the ''ode23t'' differential equations solver. This system is a moderately stiff system of differential and the ''ode45'' solver doesn't do well with these types of systems. When using ''ode23t'' is should only take a few minutes to run a 100+ second simulation while doing the same test using ''ode45'' could take 8 hours. While this is slow, it is also bad for your hard drive, as the simulation has to page between RAM and your computer's hard drive a lot.
Once this check is done, run the simulation. While it is running, check what the output structures variables are named for your RADA test system. Once the simulation is done, go to your MATLAB Workspace and select all 15 outputs for your simulation or your sub-simulation if you used '''RADA_psiCtrl_v2_lqi_est.slx'''. Save these 15 output structures to a ''.mat'' file named as the log file with _sim appended to the end of the name.
The 15 outputs are structures containing a time vector and then the data from the simulation sampled at 100 Hz and the units of this data are the SI units (ex: radians, m/s). There is one output structure for x velocity, y velocity, x body velocity, y body velocity, theta (pitch), phi (roll), psi (yaw), and one per actuator command (ex: the command sent to a wheel). Now you have all the data you can plot it.
=== Plotting Results ===
If you look at the ''DataSets'' folder below ''~/rada_research_project/MATLAB/RADA'' directory there are plenty of examples of how Paul Uhing compared simulation to test data. Generally, you should create an ''.m'' file with the same name as the log file this data was extracted from with _plot appended to the name.
Generally you can just copy and paste for ''RADA_LQG_compPID_plot.m'', ''RADA_PID_compLQG_plot.m'', ''RADA_LQG_sep_plot.m'', or ''RADA_LQG_sep_ol_plot.m'' files and rename the structures for your test.
These files create four figures. Figure 1 plots and compares the x velocity data in the first sub-figure and compares pitch (theta) data in the second sub-figure. Figure 2 does the same thing as Figure 1 but with y velocity and roll data. Figure 3 looks at the yaw data. Figure 4 looks at the sample period between UAV and ERIS packets from the camera system to check for periods of time with large packet drops.
You can follow a similar pattern to compare motor commands. Make sure that you compare Quad Motor 2 from the test data with Quad Motor 4 from simulation and vice versa because propellers 2 and 4 were switched in Eris's software compared to the Model.
That is all you need to know for testing RADA against the model.
a709db0a20ef1a133b313425a2cf610d31e04d67
344
341
2016-09-26T18:38:15Z
Pfuhing
5
/* Setting up the Camera System */
wikitext
text/x-wiki
This page will take you though setting up and testing RADA, retrieving the log file and other necessary data to run a simulation of that test and processing the data in MATLAB. Then actually running the simulation of RADA in Simulink. The initial setup and how to test the system can also be applied to demoing RADA.
== Setting Up a RADA Test ==
Testing RADA is not overly difficult once you get the hang of the steps to setup RADA. The following steps may seem like a long process to go from starting the testing process to having completed simulation and plotting of the test results but this whole test procedure (with the exception of battery charging) can be completed in about 15-20 minutes. These steps are meant to be as detailed as possible in order to help new users of RADA get up and running as quickly as possible.
'''<span style="color:red">NOTE: Always run RADA with at least 2 people!</span>''' The pendulum arm can crash into the ground if the network starts to drop packets and one person cannot give commands to RADA and spot the pendulum. This is a safety issue for both you and the RADA platform.
=== Charging Batteries ===
The lab currently uses mostly Hyperion batteries. We charge our batteries with a Hyperion EOS 1420i Net3 battery charger. For some general information about how to use this charger see [https://www.youtube.com/watch?v=-ox3EpzvsJ8 this video.]. In the lab we power this charger using the old Kepco Power supply because it is the only power supply that can supply enough current. Make sure that the power supply is set to an output voltage between 10.5V-29V.
{| class="wikitable" style="text-align:center"
|-
| [[Image:ChargerPowerSupplyOff.JPG|400px]]
| [[Image:ChargerPowerSuplyOn.JPG|400px]]
|-
| Kepco Power Supply off.
| Kepco Power Supply on with correct voltage supply range.
|}
The YouTube video link above should explain how to use the charger. RADA currently uses three different Lithium polymer (Lipo) batteries: 1600 mAh 2-cell Lipo for the wheels, 2600 mAh 2-cell Lipo for the electronics of Eris, and a 2600 mAh 4-cell Lipo for the propellers. The 1600 mAh 2-cell Lipo can be charged using memory slot 2 of the charger. The 2600 mAh 2-cell Lipos can be charged using memory slot 3 for fast charging and memory slot 4 for slower charging (use this if the battery voltage drops really low for 10-20 minutes then switch to fast charging). The 2600 mAh 4-cell Lipo can be charged using memory slot 8. The 1600 mAh 2-cell and 2600 mAh 4-cell generally charge in 10-20 minutes apiece while the 2600 mAh 2-cell generally take up to 70 minutes to charge fully.
=== Setting up the Camera System ===
The camera system is run on the windows computer CO3050-07. You can log into this computer using a local microcart username and password (not posted here for security reasons, but any one who works in the lab should know it). Once logged in, look for Tracking Tools in the start menu or look for the shortcut shown below:
[[Image:TrackingTools_shortcut.PNG|thumb|center|Tracking Tools shortcut]]
Once the program opens the screen should look something like this:
[[Image:NewTrackingTools.PNG|800px]]
In the Tracking Tools Quick Start pop up menu select Open Existing Project and then navigate to ''D:\Optitrack_Configuration'' (It should open to this directory by default) and select the most recent Tracking Tools project. It should have the naming scheme ''TrackingToolsProject YYYY-MM-DD timeStamp.ttp''. This is normally the most recently edited file when sorting by date modified. The most recent one as of August 1st, 2016 is ''TrackingToolsProject 2015-09-23 2.30pm.ttp''.
[[Image:OpeningProject.PNG|800px]]
You should notice that the cameras shown in the main project screen arrange themselves like the camera system configuration once the project has been opened. Now the constellations need to be loaded. This can be done by going to ''File->Open'' and another popup window will open. Navigate back to ''D:\Optitrack_Configuration'' (It should open to this directory by default) and select the most recently dated set of RADA trackables. They have the naming scheme ''RADA_entireSystem_M_D_YYYY.tra''. The most recent one as of August 1st, 2016 is ''RADA_entireSystem_7_8_2016.tra''.
[[Image:Opening_trackables.PNG|800px]]
Once the project and trackables are open, the cameras should appear in their constellation (square) and there should be two constellations under ''Project Explorer->Trackables''. One named UAV for the pendulum and one named ERIS for the ground vehicle. In order to get additional information about each constellation, left click on the the name of the desired trackable.
[[Image:SelectingUAV.PNG|800px]]
Once a trackable is selected more information about it is available in the ''Trackables'' Tab on the right side of the screen. For the current position and orientation look at the ''Real-Time Info'' sub-tab. The orientation of the system represented by pitch, roll, and yaw Euler Angles. The Euler Angles orientation is determined by the order the angles are solved for determine the result. Tracking Tools doesn't use the same angle calculation order as RADA uses to calculate the system orientation so unless the pendulum is held near vertical the orientation given is not correct. General speaking if the system is held so that at least 2/3 angles are near zero you can approximate the orientation seen by the system by swapping the yaw a pitch angles shown by the real time information tab.
[[Image:Uav_realTimeInfo.PNG|800px]]
Now we need to check to make sure the system is zeroed.
#Hold RADA so that the front of the ground robot (ERIS is facing the wall with the white boards (east)). The front side of Eris is labeled. If it isn't, the front is the side opposite the switches and the side with the trackable constellation on it.
#Make sure that the motor with the red motor mount is also facing the wall with the white boards.
#Make sure the quad system is aligned along Eris Axis by standing behind the system. If the system is aligned, you should be able to block the mounting bolts of the front propeller motor with the pole while facing the east wall.
#While holding the pendulum approximately vertical, see if the camera system reads zeros for the pendulum (UAV) pitch and roll (yaw and roll in ''Real-Time Info''). If yaw is off by a few degrees that is fine.
#Compare the yaw of the UAV to that of ERIS (Remember this is pitch in ''Real-Time Info''). If they are both near zero and within a few degrees and the pendulum's pitch/roll were also near zero then you are ready to use the camera system. Otherwise, go to the next step.
#You need to zero the pendulum.
##Align ERIS so it is near zero yaw first (eye ball it).
##Get a level and a friend. Have your friend use a level to ensure that the pendulum is level in both directions and hold it there.
##With the UAV constellation selected go to the ''Orientation'' tab (next to ''Real-Time Info'' tab) and click on ''Reset To Current Orientation'' button
##Now your friend can set the pendulum down and you can zero ERIS the same way.
#Save the new trackable orientation by going to ''File->Save Trackables...'' and save a file using the same naming conventions as the trackable file you opened earlier. Use the current data so you don't have to re-zero the system the next time you test.
[[Image:Uav_ResetOrientation.PNG|800px]]
=== Building Software ===
The development environment for running RADA is hosted on CO3050-11, a Linux Red Hat environment. This computer has a local ucart user name that you should use (the password isn't put here for security reasons). First, ensure that the RADA software is setup correctly for the test you want to run. To do this, you will need to open the main.cpp and logger.cpp files and make sure all of the compile time macros you want are defined correctly. All of the c++ files you should need to edit are in the directory ''~/Desktop/rada_research_project/ErisResearchCode/CppProjects/MainProgram_PacketLoss/src/Korebot'' Below are compiler macro options for main.cpp:
-'''H2ctrl''' : This will cause the system to enter H2 controller mode where the whole RADA system is controlled by an H2 controller.
-'''ssTracking''' : H2ctrl must also be defined for this macro to do anything. This macro will has the system to be controlled by a tracking H2 controller.
-'''ssMotors''' : H2ctrl must also be defined for this macro to do anything. This macro will has the system to be controlled by an H2 contorller that contains propeller states. This also causes the system to "Dance."
-'''ssDrop''' : Cause the system to go into packet drop controller mode. This mode allows controllers designed for lossy networks to be tested. Based off of other definitions how lossy the network is can be simulated. If nothing else is defined this controller becomes basically a H2 controller.
-'''drop10''' : Will put the packet drop mode into 10% loss mode and use a controller designed for 10% loss.
-'''drop30''' : Will put the packet drop mode into 30% loss mode and use a controller designed for 30% loss.
-'''drop50''' : Will put the packet drop mode into 50% loss mode and use a controller designed for 50% loss.
-'''mot50''' : This macro over-rides all other macros. If this is turned on the wheels will not run and the propellers will be run at 50% command. This is used for measuring the effective battery voltage seen by the ESCs. This is always run after a test.
-'''RADAlqi''' : This macro will cause the system to use an LQI controller on the whole system. The linear velocity states are calculated with no filter and the angular velocity states are calculated with filters.
-'''RADAlqi_est''' : This macro will cause the system to use an LQI controller on the whole system. A traditional estimator is used to estimate the states.
-'''rada_lqg''' : This macro will cause the entire system to be controlled by an LQG controller/estimator system.
-'''rada_split_lqg''' : This macro will cause the pendulum and ground robot to be controlled by their own LQG systems.
-'''rada_split_lqg_ol''' : This macro will cause the pendulum to be controlled by an LQG controller, the yaw of the ground robot to be controlled by a PID controller, and the ground robot linear velocities to be controlled with open-loop commands.
-'''yaw_off''' : This macro will cause the yaw control to be disabled on some controllers.
*'''accR''' : This macro will cause the PID linear velocity controllers to be given ramps to accelerate from one velocity to another instead of steps.
-'''posRamp''' : This macro will cause the linear velocities of RADA to be controlled by position PIDs with ramp reference instead of velocity commands.
-If no controller selection is made all controllers revert to PID controllers
All of these macros can be defined simply by uncommenting the corresponding define statement in main.cpp. The macros in the logger.cpp can be seen below:
-'''ssDrop''' : This macro puts the logger into packet drop controller mode and logs the correct values for the packet drop controllers.
-'''RADAlqi''' : This macro puts the logger into full system LQI controller logging mode.
-'''RADAlqi_est''' : This macro puts the logger into full system LQI controller plus estimator logging mode.
-'''rada_lqg''' : This puts the logger into full system LQG controller logging mode.
-'''rada_split_lqg''' : This macro causes the logger to log data about the subsystem LQG controllers.
-'''rada_split_lqg_ol''' : This cause the system to log data about the pendulum LQG system and the open-loop linear velocity commands.
-'''H2ctrl''' : This macro causes the logger to log data about the full system H2 controllers.
-If no logging mode is selected then the logger will default to logging PID data.
Because the system only calculates controllers for one set of controllers it is important to ensure that the logger is in the correct mode based off of what is defined in main.cpp. As of August 1st, 2016 the defines in main.cpp are not seen in logger.cpp.
Finally in a command prompt navigate to the driectroy: ''~/Desktop/rada_research_project/ErisResearchCode/CppProjects/MainProgram_PacketLoss''
Here just type: ''make''. The code will compile for your desired mode. For setting up a new development directory see [http://wikis.ece.iastate.edu/robotic-agriculture-data-acquisition/index.php/Setting_up_a_new_development_environment Setting up a new development environment] from the RADA Senior Design wiki.
[[Image:ComplingRADACode.png|800px]]
The complied executable code ends up in ''/home/shared/MainProject''. The ''/home/shared'' directory is setup as a network file share (NFS).
[[Image:ErisCompliedCode-config.png|800px]]
This service needs to be restarted when CO3050-11 is restarted. [http://wikis.ece.iastate.edu/robotic-agriculture-data-acquisition/index.php/Configuring_NFS_shares_for_the_robot Configure NFS shares for the robot] from the RADA Senior Design wiki. Be sure to use the new Linux install command in step six. Though I have found that even on a good strt the ''[ok]'' messages will still print.
=== Turning on RADA ===
Turning on Eris is fairly simple. Each system has its own battery. There is one for the wheels that plugs in at the front of Eris (opposite side of the switches), one for the electronics in the back of Eris (in between the switches), and one for the propellers that goes on top of Eris.
[[Image:ErisOnPhoto.jpg|800px]]
The wheel battery is normally 1600 mAh 2-cell Lipo but any 2-cell Lipo will work. The wheels are turned on by flipping the silver switch so the top points away from the system. The electronics normally use a 2600 mAh 2-cell Lipo. The electronics are turned on by flipping the green switch away from the system. It is important that you use EITHER the WIFI adapter OR hardwired Ethernet, because the VRPN may listen to the camera data broadcast over both connections which could cause problems. The propeller system is powered via a 2600 mAh 4-cell Lipo that connects to a power cable at the base of the pendulum. There is a switch to turn on the power to the propellers system. You will know it is on when the 1 on the switch is flush with the switch housing instead of sticking out. It takes about 30 seconds to a minute for Eris to boot up and start the networking connections. When the WIFI is plugged in, you will know it is ready when a blue light turns on, on the module.
=== Connecting to RADA ===
RADA is controlled through an SSH connection in a command prompt. This is not the one you compile the code from so that you can recompile for different setup without needing to close the connection. If you are using a WIFI connection, use the command ''ssh root@192.168.0.53''. If you are connected to Eris through a LAN connection use the command ''ssh root@192.168.0.54''. If the connection goes though you should be prompted for a password.
The password is ''rootme''.
[[Image:Ssh2Eris.png|800px]]
It is important to close the SSH connection before turning off Eris because the terminal you are using will hang up if you don't. You can close the connection by using the command ''exit''.
[[Image:ClosingSSH.png|800px]]
== Testing RADA ==
Now that you are connected to Eris you can run tests. The testing is started by a few different methods.
=== Running the First Test After Power Up ===
For the first test after powering on Eris, a few additional steps need to be completed in order to test the system. The FPGA motor controller needs to be programmed and Eris needs to connect to the NFS server running on CO3050-11. This is accomplished by running ''1_co3050-11.sh'', this shell script will setup the NFS, and load the bit file into the FPGA configuration memory. Then it retrieves the executable file from the NFS server ''/mnt/nfs/MainProject'' and runs the executable. Once the user exits the executable, the log file produced is copied from the ''~/Logs/YYYY_MM_DD_Day'' directory on Eris to ''/home/shared/MainProject/Logs/YYYY_MM_DD_Day'' on CO3050-11. When the folder for the current Eris date doesn't exist, it creates this directory in CO3050-11 and then removes the directory and log file from Eris. You may see a warning that when copying the log file Eris couldn't maintain the file permission settings. This is normal as Eris doesn't have the same access to the NSF server as it has to its own files. This date stamp uses the date on Eris, which is currently in June of 2008 as of August 2nd, 2016.
Before starting the test, it is best to have someone spotting the pendulum and holding it near vertical so that the pendulum doesn't have issues when entering a control mode.'''<span style="color:red"> Always ensure the pendulum is spotted by a second person when testing so you don't hurt yourself, others in the lab, or the RADA system.</span>''' Once the spotter is ready, run the shell script by using the command ''./1_co3050-11.sh'' in the terminal with the open SSH connection to Eris from the home, ''/root'', directory of Eris. When you run this script there will be a bunch of information printed out about the PIC bus and loading the bit file to configure the FPGA. You will know that RADA is ready for the test when it asks you to select a running mode. See the Testing Modes section below. This script can take a while to complete so beyond the first test after startup you don't need to run this script. See the Section about Running additional tests below.r
[[Image:StartingRADA initial.png|800px]]
=== Testing Modes ===
The RADA system has three testing modes: Robot Control Mode, Tuning Mode, and Box Step Mode. Additionally, you can exit the execution at any time by pressing the ''Esc'' key. Once the terminal asks you to chose a mode, you can use the following commands to enter the desired mode with a three-second delay or exit the program. You can also use these commands to switch between the modes.
-''v'' : Enters the pendulum PID tuning mode - this will only really work when using PIDs to control the pendulum.
-''b'' : Enter robot control mode - in this mode you can drive the robot around and the pendulum will try to stay vertical. This is the main mode used for testing the whole RADA system.
-''n'' : Enters box step mode - the pendulum will change its desired pitch and roll angles every 20 seconds and move in a box shape.
-''Esc'' : By hitting the escape key the program will exit the program.
You will almost always want to run Robot Control Mode as the other modes are legacy modes from when we initially built and tested RADA and only works with the pendulum PID controllers. There are also a few utility commands that can be used in all modes.
-''2'' : Resets I composts of the Pitch/Roll PIDs and only the PIDs.
-''m'' : Adds a marker to the Log file in case odd things happen somewhere. This just increments a counter, so if you use it, look for changes in the marker value.
==== Robot Control Mode ====
In Robot control mode you can control the motion of Eris. For PID control of Eris or 1D state feedback system the directional commands command Eris body velocity were for full system and Eris system state feedback controllers control the global velocity. All of these keys only need to be pressed not held down.
-''w'' : Moves Eris forward (+x) at some velocity depending on the controller.
-''s'' : Moves Eris in reverse (-x) at some velocity depending on the controller.
-''d'' : Moves Eris in right (+y) at some velocity depending on the controller.
-''a'' : Moves Eris in left (-y) at some velocity depending on the controller.
-''p'' : Stops the motion of Eris (Set all velocity set points to zero). I.e. if you hit ''w'' then hit ''s'' then Eris will be moving in reverse.
-''y'' : Moves Eris forward and to the right (+x/+y) simultaneously at some velocity depending on the controller.
-''t'' : Moves Eris forward and to the left (+x/-y) simultaneously at some velocity depending on the controller.
-''i'' : Moves Eris reverse and to the right (-x/+y) simultaneously at some velocity depending on the controller.
-''y'' : Moves Eris reverse and to the left (-x/-y) simultaneously at some velocity depending on the controller.
-''e'' : Rotate Eris clockwise (+yaw) at some angular rate. This only worked when RADA used the closed-loop FPGA control of the wheels. There is currently no controllers that use this command.
-''q'' : Rotate Eris counter-clockwise (-yaw) at some angular rate. This only worked when RADA used the closed-loop FPGA control of the wheels. There is currently no controllers that use this command.
-''<'' : Increment Eris' desired heading 45 degrees counter-clockwise (-yaw).
-''>'' : Increment Eris' desired heading 45 degrees clockwise (+yaw).
-''7'' : Increments the pitch set point (+pitch).
-''4'' : Decrements the pitch set point (-pitch).
-''8'' : Increments the roll set point (+roll).
-''5'' : Decrements the roll set point (-roll).
==== Tuning Mode ====
Tuning mode allows you to tune the PID controllers for both pitch and roll. The UI commands here are also available in Box Step Mode.
-''1'' : Tune the Pitch PID.
-''3'' : Tune the Roll PID.
-''7'' : Increase proportional gain of PID being tuned.
-''4'' : Decrease proportional gain of PID being tuned.
-''8'' : Increase integral gain of PID being tuned.
-''5'' : Decrease integral gain of PID being tuned.
-''9'' : Increase derivative gain of PID being tuned.
-''6'' : Decrease derivative gain of PID being tuned.
-''i'' : Increase set point of PID being tuned.
-''k'' : Decrease set point of PID being tuned.
-''o'' : Increase integral windup term of PID being tuned. (Not used)
-''l'' : Decrease integral windup term of PID being tuned. (Not used)
==== Box Step Mode ====
Box step mode will automatically change the set points of the pendulum every 20 seconds. The case statement for this mode can be changed for 1D and 2D step modes. This mode allows the user to use the same commands as Tuning Mode.
=== Running Additional Tests ===
Once you have run one test with Eris on, it is unnecessary to configure the FPGA or connect to the NFS server again. This is what took much of the time in the initial setup. This is what the script ''3_start_eris.sh'' was developed for. It does everything that ''1_co3050-11.sh'' does but without reprogramming the FPGA or reconnecting to the NFS server. As a result, it is ready to test much quicker.
Before starting the test, it is best to have someone spotting the pendulum and holding it near vertical so that the pendulum doesn't have issues when entering a control mode.'''<span style="color:red"> Always ensure the pendulum is spotted by a second person when testing so you don't hurt yourself, others in the lab, or the RADA system.</span>''' Once you spotter is ready run the shell script by using the command ''./3_start_eris.sh'' in the terminal with the open SSH connection to Eris from the home, ''/root'', directory of Eris.
[[Image:StartingRADA2nd.png|800px]]
=== Locating and Retrieving Log Files ===
If you are only demoing the system, there is no need to go beyond this point. Once you are done with a test that you want to compare to the model you should retrieve the log file right away so you don't mix it up with other test. On CO3050-11 go to the dircetory ''/home/shared/MainProject/Logs'' using the file browser (you can do this in a terminal but it is easier from the file explorer). Once there, look for the folder that has been modified most recently as Eris date is normally out of sync with its date and time. Then look for the newest log file. Log files have the naming scheme ''log(hh.mm.ss).txt'' (ex. log(13.04.51).txt). This naming convention works well to ensure that no log file is over written but it isn't useful for describing what the test was conducted for. Copy this log to the Desktop or to a USB drive and rename it. A good method is to name the file something like ''RADA_ctrl_otherNote#.txt'', where Describes what system you tested (ex. RADA, RADA1D, PEN1D, PEN2D), what typ of controller was used, other notes and then a number if this is a repeat of another test. This is much more useful when looking back at these logs later on. Before transferring the log file for processing you should record the wheel and propeller battery voltages in the header of the log file. The log file format is both human readable and can be parsed by MATALB. It was designed by the first RADA Senior Design Team and more information about the log files can be found [http://wikis.ece.iastate.edu/robotic-agriculture-data-acquisition/index.php/Data_Analysis_Tool here.] See he section below on measuring battery voltage below in order to get the best measurements for simulation of RADA.
=== Measuring Battery Voltages ===
The last thing that you need to do before simulating an experiment of the RADA platform is record the battery voltages for both the wheels and propellers. The wheel battery can be measured unloaded as there aren't large line losses between the battery and the H-bridges. The propeller battery voltage needs to be measured under load because the power cord running up the pendulum has significant line losses at the currents the propellers draw when in use. The battery voltages can be recorded in the log file for the test. Open the log file for the test you just completed (Use KWrite for Linux machines or Notepad++ for Windows machines). The first few lines of the log are the header. It should look like this:
#Constants pitch_P pitch_I pitch_D
#PIDValues 48000 18000 21000
#Constants roll_P roll_I roll_D
#PIDValues 48000 18000 21000
#Battery Vquad Vwheels
#Voltage
Follow the procedure for measuring the voltage of each battery and then record the voltage under the corresponding battery. Then save the log file and close out of your text editor and the test will be ready for processing. Recoding the battery voltages in this way makes it much easier to find if you need the value later. The final log file header should look like this once you are done
#Constants pitch_P pitch_I pitch_D
#PIDValues 48000 18000 21000
#Constants roll_P roll_I roll_D
#PIDValues 48000 18000 21000
#Battery Vquad Vwheels
#Voltage 14.44 8.257
==== Wheel Battery ====
#After test disconnect wheel battery from the system.
#Measure voltage of battery using multimeter.
[[Image:MeasureVwheel.jpg|800px]]
You can use the plug used for charging the 2-cell Lipos but make sure to connect the plug to the multimeter before connecting the battery and disconnect the battery before disconnecting the plug from the mulitmeter. It is generally the best practice to give the multimeter a few minutes to allow for the voltage measurement to stabilize as the battery measurement tends to be a little low right after the test. The multimeter will report data out to four decimal places it is best just to round to three decimal places for the wheel voltage.
==== Propeller Battery ====
#Setup code to run all four propellers at 50% throttle, uncomment the definition of ''mot50'' in main.cpp and compile the project.
#Power off propellers by turning off the switch to the ESCs.
#Connect multimeter to measure the voltage across one of the ESCs. This is done by using the power splitter cord.
##Connect one of the female XT60 connectors on the splitter to a male XT60 connector to banana connector cable.
##The banana connector connects to the hand held multimeter. The multimeter should be set to the 20VDC measurement setting.
##Next unplug one the ESCs' power connection.
##Reconnect the ESC to power through the two remain connectors on the splitter cable.
#Power on the propellers.
#Run the system at 50% throttle and measure the steady-state voltage during the test. The battery will slow the voltage decay significantly, meaning it will keep the same measurement for a few seconds.
#Stop the test and record the voltage in the log file. Make sure to disconnect the battery before removing the splitter cable.
{| class="wikitable" style="text-align:center"
|-
| [[Image:PowerSplitter.jpg|200px]]
| [[Image:QuadMultiCon.jpg |200px]]
| [[Image:QuadMultiSet.JPG |200px]]
| [[Image:QuadMeasESCcon.JPG|200px]]
|-
| Splitter cord.
| Connect splitter to multimeter.
| Settings for multimeter.
| Connecting ESC through splitter.
|}
The testing setup should look like the image below:
[[Image:QuadBattMeas.jpg|800px]]
== Post Processing and Simulation ==
Simulating a test of RADA starts with processing and storing the data. Then all of the parameters of the model are loaded in the MATLAB Workspace. Next, the Simulink file used for the simulation is opened and the length of the simulation is set to match the length of the actual test. The simulation is run and the simulation output is stored. Finally, the data should be plotted and compared.
=== Using the MATLAB Data Parsing Tool ===
In-depth discussion of how to use the log file parsing tool is described [http://wikis.ece.iastate.edu/robotic-agriculture-data-acquisition/index.php/Data_Analysis_Tool here.] It is suggested to use the version of the tool in the rada_resarch_project git repository Paul Uhing used for his Master's research. It can be found on CO3050-11 under the ucart account in the directory ''~/rada_research_project/DataAnalysiTool_omnicoor/Tool''. Simply open MATLAB and set the working directory to this file path. In the MATLAB Command Prompt run ''DataAnalysis''. A popup window should open up. Select the log file you want to process and wait for the tool to finish processing the file. Once this is complete there should be four structures in the MATLAB workspace.
-'''main''' : This contains all of the data extracted from the log file and the processing parameters used. main.expData contains two time structures: Time is used for the pendulum data and Eris_time is used for the ground vehicle data.
-'''X_ref''' : This contains the reference vector in m/s for x velocity that is fed into Simulink. This expedites the simulation setup process, this used to be done by hand.
-'''Y_ref''' : This contains the reference vector in m/s for y velocity that is fed into Simulink. This expedites the simulation setup process, this used to be done by hand.
-'''Yaw_ref''' : This contains the reference vector in radians for yaw that is fed into Simulink. This expedites the simulation setup process, this used to be done by hand. This one is new in case people start testing the system with heading changes but is not used in the current setup.
The first thing you should do is rename the main structure to the name you used for the log file. This is helpful for comparing multiple tests. Next, you will want to create two new variable ''Vquad_test'' and ''Vw_test''. In the MATLAB Command Prompt set the measured propeller voltage from the log file to ''Vquad_test'' and set the measured wheel voltage to ''Vw_test'' as this will be used by the simulation. Finally, if you did an open-loop test of the wheels create the variable ''Uol'' and set it to the open-loop wheel command used. Save all of these variables from the MATLAB workspace to a ''.mat'' file of the same name as the log file you extracted the data from and save it in the same directory as your RADA Simulink files. As of August 2nd, 2016 this directory is ''~/rada_research_project/MATLAB/RADA.''
=== Setting up the MATLAB Workspace for Simulation ===
Change your MATLAB directory to this directory. Then run the simulation setup files. Currently, you only need to run ''modelParams_smallWheels_RADA'' in the MATLAB Command Prompt. Next, open the Simulink file that contains the model of RADA controlled by the controller you tested.
-'''RADA_psiCtrl_v2_lqi_est.slx''' contains LQI, LQI+estimation, and LQG controller simulations.
-'''RADA_psiCtrl_v2.slx''' contains the PID controlled system.
-'''RADA_psiCtrl_v2_LQGsep.slx''' contains the subsystem LQG controlled system.
-'''RADA_psiCtrl_v2_LQGsep_ol.slx''' contains the simulation of the pendulum system controlled by an LQG and Eris controlled with open-loop commands.
Note all of the current (August 2nd, 2016) ''.slx'' files were created in MATLAB 2014b and will only work in MATLAB 2014b or newer. Then in the MATLAB Command Prompt type ''X_ref.time(end)'' exactly, don't add a semicolon, and hit enter. MATLAB will print the time of the last command in the X_ref structure. Set the end time of the simulation to this value and save your Simulink file.
=== Running Simulations and Storing Results ===
Before running the simulation make sure that the simulation is using the ''ode23t'' differential equations solver. This system is a moderately stiff system of differential and the ''ode45'' solver doesn't do well with these types of systems. When using ''ode23t'' is should only take a few minutes to run a 100+ second simulation while doing the same test using ''ode45'' could take 8 hours. While this is slow, it is also bad for your hard drive, as the simulation has to page between RAM and your computer's hard drive a lot.
Once this check is done, run the simulation. While it is running, check what the output structures variables are named for your RADA test system. Once the simulation is done, go to your MATLAB Workspace and select all 15 outputs for your simulation or your sub-simulation if you used '''RADA_psiCtrl_v2_lqi_est.slx'''. Save these 15 output structures to a ''.mat'' file named as the log file with _sim appended to the end of the name.
The 15 outputs are structures containing a time vector and then the data from the simulation sampled at 100 Hz and the units of this data are the SI units (ex: radians, m/s). There is one output structure for x velocity, y velocity, x body velocity, y body velocity, theta (pitch), phi (roll), psi (yaw), and one per actuator command (ex: the command sent to a wheel). Now you have all the data you can plot it.
=== Plotting Results ===
If you look at the ''DataSets'' folder below ''~/rada_research_project/MATLAB/RADA'' directory there are plenty of examples of how Paul Uhing compared simulation to test data. Generally, you should create an ''.m'' file with the same name as the log file this data was extracted from with _plot appended to the name.
Generally you can just copy and paste for ''RADA_LQG_compPID_plot.m'', ''RADA_PID_compLQG_plot.m'', ''RADA_LQG_sep_plot.m'', or ''RADA_LQG_sep_ol_plot.m'' files and rename the structures for your test.
These files create four figures. Figure 1 plots and compares the x velocity data in the first sub-figure and compares pitch (theta) data in the second sub-figure. Figure 2 does the same thing as Figure 1 but with y velocity and roll data. Figure 3 looks at the yaw data. Figure 4 looks at the sample period between UAV and ERIS packets from the camera system to check for periods of time with large packet drops.
You can follow a similar pattern to compare motor commands. Make sure that you compare Quad Motor 2 from the test data with Quad Motor 4 from simulation and vice versa because propellers 2 and 4 were switched in Eris's software compared to the Model.
That is all you need to know for testing RADA against the model.
31fb76a716619ebca86fd1ba5cf623071c57c9d0
345
344
2016-09-26T18:45:49Z
Pfuhing
5
/* Building Software */
wikitext
text/x-wiki
This page will take you though setting up and testing RADA, retrieving the log file and other necessary data to run a simulation of that test and processing the data in MATLAB. Then actually running the simulation of RADA in Simulink. The initial setup and how to test the system can also be applied to demoing RADA.
== Setting Up a RADA Test ==
Testing RADA is not overly difficult once you get the hang of the steps to setup RADA. The following steps may seem like a long process to go from starting the testing process to having completed simulation and plotting of the test results but this whole test procedure (with the exception of battery charging) can be completed in about 15-20 minutes. These steps are meant to be as detailed as possible in order to help new users of RADA get up and running as quickly as possible.
'''<span style="color:red">NOTE: Always run RADA with at least 2 people!</span>''' The pendulum arm can crash into the ground if the network starts to drop packets and one person cannot give commands to RADA and spot the pendulum. This is a safety issue for both you and the RADA platform.
=== Charging Batteries ===
The lab currently uses mostly Hyperion batteries. We charge our batteries with a Hyperion EOS 1420i Net3 battery charger. For some general information about how to use this charger see [https://www.youtube.com/watch?v=-ox3EpzvsJ8 this video.]. In the lab we power this charger using the old Kepco Power supply because it is the only power supply that can supply enough current. Make sure that the power supply is set to an output voltage between 10.5V-29V.
{| class="wikitable" style="text-align:center"
|-
| [[Image:ChargerPowerSupplyOff.JPG|400px]]
| [[Image:ChargerPowerSuplyOn.JPG|400px]]
|-
| Kepco Power Supply off.
| Kepco Power Supply on with correct voltage supply range.
|}
The YouTube video link above should explain how to use the charger. RADA currently uses three different Lithium polymer (Lipo) batteries: 1600 mAh 2-cell Lipo for the wheels, 2600 mAh 2-cell Lipo for the electronics of Eris, and a 2600 mAh 4-cell Lipo for the propellers. The 1600 mAh 2-cell Lipo can be charged using memory slot 2 of the charger. The 2600 mAh 2-cell Lipos can be charged using memory slot 3 for fast charging and memory slot 4 for slower charging (use this if the battery voltage drops really low for 10-20 minutes then switch to fast charging). The 2600 mAh 4-cell Lipo can be charged using memory slot 8. The 1600 mAh 2-cell and 2600 mAh 4-cell generally charge in 10-20 minutes apiece while the 2600 mAh 2-cell generally take up to 70 minutes to charge fully.
=== Setting up the Camera System ===
The camera system is run on the windows computer CO3050-07. You can log into this computer using a local microcart username and password (not posted here for security reasons, but any one who works in the lab should know it). Once logged in, look for Tracking Tools in the start menu or look for the shortcut shown below:
[[Image:TrackingTools_shortcut.PNG|thumb|center|Tracking Tools shortcut]]
Once the program opens the screen should look something like this:
[[Image:NewTrackingTools.PNG|800px]]
In the Tracking Tools Quick Start pop up menu select Open Existing Project and then navigate to ''D:\Optitrack_Configuration'' (It should open to this directory by default) and select the most recent Tracking Tools project. It should have the naming scheme ''TrackingToolsProject YYYY-MM-DD timeStamp.ttp''. This is normally the most recently edited file when sorting by date modified. The most recent one as of August 1st, 2016 is ''TrackingToolsProject 2015-09-23 2.30pm.ttp''.
[[Image:OpeningProject.PNG|800px]]
You should notice that the cameras shown in the main project screen arrange themselves like the camera system configuration once the project has been opened. Now the constellations need to be loaded. This can be done by going to ''File->Open'' and another popup window will open. Navigate back to ''D:\Optitrack_Configuration'' (It should open to this directory by default) and select the most recently dated set of RADA trackables. They have the naming scheme ''RADA_entireSystem_M_D_YYYY.tra''. The most recent one as of August 1st, 2016 is ''RADA_entireSystem_7_8_2016.tra''.
[[Image:Opening_trackables.PNG|800px]]
Once the project and trackables are open, the cameras should appear in their constellation (square) and there should be two constellations under ''Project Explorer->Trackables''. One named UAV for the pendulum and one named ERIS for the ground vehicle. In order to get additional information about each constellation, left click on the the name of the desired trackable.
[[Image:SelectingUAV.PNG|800px]]
Once a trackable is selected more information about it is available in the ''Trackables'' Tab on the right side of the screen. For the current position and orientation look at the ''Real-Time Info'' sub-tab. The orientation of the system represented by pitch, roll, and yaw Euler Angles. The Euler Angles orientation is determined by the order the angles are solved for determine the result. Tracking Tools doesn't use the same angle calculation order as RADA uses to calculate the system orientation so unless the pendulum is held near vertical the orientation given is not correct. General speaking if the system is held so that at least 2/3 angles are near zero you can approximate the orientation seen by the system by swapping the yaw a pitch angles shown by the real time information tab.
[[Image:Uav_realTimeInfo.PNG|800px]]
Now we need to check to make sure the system is zeroed.
#Hold RADA so that the front of the ground robot (ERIS is facing the wall with the white boards (east)). The front side of Eris is labeled. If it isn't, the front is the side opposite the switches and the side with the trackable constellation on it.
#Make sure that the motor with the red motor mount is also facing the wall with the white boards.
#Make sure the quad system is aligned along Eris Axis by standing behind the system. If the system is aligned, you should be able to block the mounting bolts of the front propeller motor with the pole while facing the east wall.
#While holding the pendulum approximately vertical, see if the camera system reads zeros for the pendulum (UAV) pitch and roll (yaw and roll in ''Real-Time Info''). If yaw is off by a few degrees that is fine.
#Compare the yaw of the UAV to that of ERIS (Remember this is pitch in ''Real-Time Info''). If they are both near zero and within a few degrees and the pendulum's pitch/roll were also near zero then you are ready to use the camera system. Otherwise, go to the next step.
#You need to zero the pendulum.
##Align ERIS so it is near zero yaw first (eye ball it).
##Get a level and a friend. Have your friend use a level to ensure that the pendulum is level in both directions and hold it there.
##With the UAV constellation selected go to the ''Orientation'' tab (next to ''Real-Time Info'' tab) and click on ''Reset To Current Orientation'' button
##Now your friend can set the pendulum down and you can zero ERIS the same way.
#Save the new trackable orientation by going to ''File->Save Trackables...'' and save a file using the same naming conventions as the trackable file you opened earlier. Use the current data so you don't have to re-zero the system the next time you test.
[[Image:Uav_ResetOrientation.PNG|800px]]
=== Building Software ===
The development environment for running RADA is hosted on CO3050-11, a Linux Red Hat environment. This computer has a local ucart user name that you should use (the password isn't put here for security reasons). First, ensure that the RADA software is setup correctly for the test you want to run. To do this, you will need to open the main.cpp and logger.cpp files and make sure all of the compile time macros you want are defined correctly. All of the c++ files you should need to edit are in the directory ''~/Desktop/rada_research_project/ErisResearchCode/CppProjects/MainProgram_PacketLoss/src/Korebot'' Below are compiler macro options for main.cpp:
-'''H2ctrl''' : This will cause the system to enter H2 controller mode where the whole RADA system is controlled by an H2 controller.
-'''ssTracking''' : H2ctrl must also be defined for this macro to do anything. This macro will control using a tracking H2 controller. This controller doesn't have propeller velocity states so the controller makes use of the propellers.
-'''ssMotors''' : H2ctrl must also be defined for this macro to do anything. This macro will control the system using a H2 controller that contains propeller velocity states. This also causes the system to "Dance" because the propellers are slower than the wheels so the H2 controller will not use the propellers.
-'''ssDrop''' : Cause the system to go into packet drop controller mode. This mode allows controllers designed for lossy networks to be tested. Based off of other definitions how lossy the network is can be simulated. If nothing else is defined this controller becomes basically a H2 controller.
-'''drop10''' : Will put the packet drop mode into 10% loss mode and use a controller designed for 10% loss.
-'''drop30''' : Will put the packet drop mode into 30% loss mode and use a controller designed for 30% loss.
-'''drop50''' : Will put the packet drop mode into 50% loss mode and use a controller designed for 50% loss.
-'''mot50''' : This macro over-rides all other macros. If this is turned on the wheels will not run and the propellers will be run at 50% command. This is used for measuring the effective battery voltage seen by the ESCs. This is always run after a test.
-'''RADAlqi''' : This macro will cause the system to use an LQI controller on the whole system. The linear velocity states are calculated with no filter and the angular velocity states are calculated with filters.
-'''RADAlqi_est''' : This macro will cause the system to use an LQI controller on the whole system. A traditional estimator is used to estimate the states.
-'''rada_lqg''' : This macro will cause the entire system to be controlled by an LQG controller/estimator system.
-'''rada_split_lqg''' : This macro will cause the pendulum and ground robot to be controlled by their own LQG systems.
-'''rada_split_lqg_ol''' : This macro will cause the pendulum to be controlled by an LQG controller, the yaw of the ground robot to be controlled by a PID controller, and the ground robot linear velocities to be controlled with open-loop commands.
-'''yaw_off''' : This macro will cause the yaw control to be disabled on some controllers.
*'''accR''' : This macro will cause the PID linear velocity controllers to be given ramps to accelerate from one velocity to another instead of steps.
-'''posRamp''' : This macro will cause the linear velocities of RADA to be controlled by position PIDs with ramp reference instead of velocity commands.
-If no controller selection is made all controllers revert to PID controllers
All of these macros can be defined simply by uncommenting the corresponding define statement in main.cpp. The macros in the logger.cpp can be seen below:
-'''ssDrop''' : This macro puts the logger into packet drop controller mode and logs the correct values for the packet drop controllers.
-'''RADAlqi''' : This macro puts the logger into full system LQI controller logging mode.
-'''RADAlqi_est''' : This macro puts the logger into full system LQI controller plus estimator logging mode.
-'''rada_lqg''' : This puts the logger into full system LQG controller logging mode.
-'''rada_split_lqg''' : This macro causes the logger to log data about the subsystem LQG controllers.
-'''rada_split_lqg_ol''' : This cause the system to log data about the pendulum LQG system and the open-loop linear velocity commands.
-'''H2ctrl''' : This macro causes the logger to log data about the full system H2 controllers.
-If no logging mode is selected then the logger will default to logging PID data.
Because the system only calculates controllers for one set of controllers it is important to ensure that the logger is in the correct mode based off of what is defined in main.cpp. As of August 1st, 2016 the defines in main.cpp are not seen in logger.cpp.
Finally in a command prompt navigate to the driectroy: ''~/Desktop/rada_research_project/ErisResearchCode/CppProjects/MainProgram_PacketLoss''
Here just type: ''make''. The code will compile for your desired mode. For setting up a new development directory see [http://wikis.ece.iastate.edu/robotic-agriculture-data-acquisition/index.php/Setting_up_a_new_development_environment Setting up a new development environment] from the RADA Senior Design wiki.
[[Image:ComplingRADACode.png|800px]]
The complied executable code ends up in ''/home/shared/MainProject''. The ''/home/shared'' directory is setup as a network file share (NFS).
[[Image:ErisCompliedCode-config.png|800px]]
This service needs to be restarted when CO3050-11 is restarted. [http://wikis.ece.iastate.edu/robotic-agriculture-data-acquisition/index.php/Configuring_NFS_shares_for_the_robot Configure NFS shares for the robot] from the RADA Senior Design wiki. Be sure to use the new Linux install command in step six. Though I have found that even on a good strt the ''[ok]'' messages will still print.
=== Turning on RADA ===
Turning on Eris is fairly simple. Each system has its own battery. There is one for the wheels that plugs in at the front of Eris (opposite side of the switches), one for the electronics in the back of Eris (in between the switches), and one for the propellers that goes on top of Eris.
[[Image:ErisOnPhoto.jpg|800px]]
The wheel battery is normally 1600 mAh 2-cell Lipo but any 2-cell Lipo will work. The wheels are turned on by flipping the silver switch so the top points away from the system. The electronics normally use a 2600 mAh 2-cell Lipo. The electronics are turned on by flipping the green switch away from the system. It is important that you use EITHER the WIFI adapter OR hardwired Ethernet, because the VRPN may listen to the camera data broadcast over both connections which could cause problems. The propeller system is powered via a 2600 mAh 4-cell Lipo that connects to a power cable at the base of the pendulum. There is a switch to turn on the power to the propellers system. You will know it is on when the 1 on the switch is flush with the switch housing instead of sticking out. It takes about 30 seconds to a minute for Eris to boot up and start the networking connections. When the WIFI is plugged in, you will know it is ready when a blue light turns on, on the module.
=== Connecting to RADA ===
RADA is controlled through an SSH connection in a command prompt. This is not the one you compile the code from so that you can recompile for different setup without needing to close the connection. If you are using a WIFI connection, use the command ''ssh root@192.168.0.53''. If you are connected to Eris through a LAN connection use the command ''ssh root@192.168.0.54''. If the connection goes though you should be prompted for a password.
The password is ''rootme''.
[[Image:Ssh2Eris.png|800px]]
It is important to close the SSH connection before turning off Eris because the terminal you are using will hang up if you don't. You can close the connection by using the command ''exit''.
[[Image:ClosingSSH.png|800px]]
== Testing RADA ==
Now that you are connected to Eris you can run tests. The testing is started by a few different methods.
=== Running the First Test After Power Up ===
For the first test after powering on Eris, a few additional steps need to be completed in order to test the system. The FPGA motor controller needs to be programmed and Eris needs to connect to the NFS server running on CO3050-11. This is accomplished by running ''1_co3050-11.sh'', this shell script will setup the NFS, and load the bit file into the FPGA configuration memory. Then it retrieves the executable file from the NFS server ''/mnt/nfs/MainProject'' and runs the executable. Once the user exits the executable, the log file produced is copied from the ''~/Logs/YYYY_MM_DD_Day'' directory on Eris to ''/home/shared/MainProject/Logs/YYYY_MM_DD_Day'' on CO3050-11. When the folder for the current Eris date doesn't exist, it creates this directory in CO3050-11 and then removes the directory and log file from Eris. You may see a warning that when copying the log file Eris couldn't maintain the file permission settings. This is normal as Eris doesn't have the same access to the NSF server as it has to its own files. This date stamp uses the date on Eris, which is currently in June of 2008 as of August 2nd, 2016.
Before starting the test, it is best to have someone spotting the pendulum and holding it near vertical so that the pendulum doesn't have issues when entering a control mode.'''<span style="color:red"> Always ensure the pendulum is spotted by a second person when testing so you don't hurt yourself, others in the lab, or the RADA system.</span>''' Once the spotter is ready, run the shell script by using the command ''./1_co3050-11.sh'' in the terminal with the open SSH connection to Eris from the home, ''/root'', directory of Eris. When you run this script there will be a bunch of information printed out about the PIC bus and loading the bit file to configure the FPGA. You will know that RADA is ready for the test when it asks you to select a running mode. See the Testing Modes section below. This script can take a while to complete so beyond the first test after startup you don't need to run this script. See the Section about Running additional tests below.r
[[Image:StartingRADA initial.png|800px]]
=== Testing Modes ===
The RADA system has three testing modes: Robot Control Mode, Tuning Mode, and Box Step Mode. Additionally, you can exit the execution at any time by pressing the ''Esc'' key. Once the terminal asks you to chose a mode, you can use the following commands to enter the desired mode with a three-second delay or exit the program. You can also use these commands to switch between the modes.
-''v'' : Enters the pendulum PID tuning mode - this will only really work when using PIDs to control the pendulum.
-''b'' : Enter robot control mode - in this mode you can drive the robot around and the pendulum will try to stay vertical. This is the main mode used for testing the whole RADA system.
-''n'' : Enters box step mode - the pendulum will change its desired pitch and roll angles every 20 seconds and move in a box shape.
-''Esc'' : By hitting the escape key the program will exit the program.
You will almost always want to run Robot Control Mode as the other modes are legacy modes from when we initially built and tested RADA and only works with the pendulum PID controllers. There are also a few utility commands that can be used in all modes.
-''2'' : Resets I composts of the Pitch/Roll PIDs and only the PIDs.
-''m'' : Adds a marker to the Log file in case odd things happen somewhere. This just increments a counter, so if you use it, look for changes in the marker value.
==== Robot Control Mode ====
In Robot control mode you can control the motion of Eris. For PID control of Eris or 1D state feedback system the directional commands command Eris body velocity were for full system and Eris system state feedback controllers control the global velocity. All of these keys only need to be pressed not held down.
-''w'' : Moves Eris forward (+x) at some velocity depending on the controller.
-''s'' : Moves Eris in reverse (-x) at some velocity depending on the controller.
-''d'' : Moves Eris in right (+y) at some velocity depending on the controller.
-''a'' : Moves Eris in left (-y) at some velocity depending on the controller.
-''p'' : Stops the motion of Eris (Set all velocity set points to zero). I.e. if you hit ''w'' then hit ''s'' then Eris will be moving in reverse.
-''y'' : Moves Eris forward and to the right (+x/+y) simultaneously at some velocity depending on the controller.
-''t'' : Moves Eris forward and to the left (+x/-y) simultaneously at some velocity depending on the controller.
-''i'' : Moves Eris reverse and to the right (-x/+y) simultaneously at some velocity depending on the controller.
-''y'' : Moves Eris reverse and to the left (-x/-y) simultaneously at some velocity depending on the controller.
-''e'' : Rotate Eris clockwise (+yaw) at some angular rate. This only worked when RADA used the closed-loop FPGA control of the wheels. There is currently no controllers that use this command.
-''q'' : Rotate Eris counter-clockwise (-yaw) at some angular rate. This only worked when RADA used the closed-loop FPGA control of the wheels. There is currently no controllers that use this command.
-''<'' : Increment Eris' desired heading 45 degrees counter-clockwise (-yaw).
-''>'' : Increment Eris' desired heading 45 degrees clockwise (+yaw).
-''7'' : Increments the pitch set point (+pitch).
-''4'' : Decrements the pitch set point (-pitch).
-''8'' : Increments the roll set point (+roll).
-''5'' : Decrements the roll set point (-roll).
==== Tuning Mode ====
Tuning mode allows you to tune the PID controllers for both pitch and roll. The UI commands here are also available in Box Step Mode.
-''1'' : Tune the Pitch PID.
-''3'' : Tune the Roll PID.
-''7'' : Increase proportional gain of PID being tuned.
-''4'' : Decrease proportional gain of PID being tuned.
-''8'' : Increase integral gain of PID being tuned.
-''5'' : Decrease integral gain of PID being tuned.
-''9'' : Increase derivative gain of PID being tuned.
-''6'' : Decrease derivative gain of PID being tuned.
-''i'' : Increase set point of PID being tuned.
-''k'' : Decrease set point of PID being tuned.
-''o'' : Increase integral windup term of PID being tuned. (Not used)
-''l'' : Decrease integral windup term of PID being tuned. (Not used)
==== Box Step Mode ====
Box step mode will automatically change the set points of the pendulum every 20 seconds. The case statement for this mode can be changed for 1D and 2D step modes. This mode allows the user to use the same commands as Tuning Mode.
=== Running Additional Tests ===
Once you have run one test with Eris on, it is unnecessary to configure the FPGA or connect to the NFS server again. This is what took much of the time in the initial setup. This is what the script ''3_start_eris.sh'' was developed for. It does everything that ''1_co3050-11.sh'' does but without reprogramming the FPGA or reconnecting to the NFS server. As a result, it is ready to test much quicker.
Before starting the test, it is best to have someone spotting the pendulum and holding it near vertical so that the pendulum doesn't have issues when entering a control mode.'''<span style="color:red"> Always ensure the pendulum is spotted by a second person when testing so you don't hurt yourself, others in the lab, or the RADA system.</span>''' Once you spotter is ready run the shell script by using the command ''./3_start_eris.sh'' in the terminal with the open SSH connection to Eris from the home, ''/root'', directory of Eris.
[[Image:StartingRADA2nd.png|800px]]
=== Locating and Retrieving Log Files ===
If you are only demoing the system, there is no need to go beyond this point. Once you are done with a test that you want to compare to the model you should retrieve the log file right away so you don't mix it up with other test. On CO3050-11 go to the dircetory ''/home/shared/MainProject/Logs'' using the file browser (you can do this in a terminal but it is easier from the file explorer). Once there, look for the folder that has been modified most recently as Eris date is normally out of sync with its date and time. Then look for the newest log file. Log files have the naming scheme ''log(hh.mm.ss).txt'' (ex. log(13.04.51).txt). This naming convention works well to ensure that no log file is over written but it isn't useful for describing what the test was conducted for. Copy this log to the Desktop or to a USB drive and rename it. A good method is to name the file something like ''RADA_ctrl_otherNote#.txt'', where Describes what system you tested (ex. RADA, RADA1D, PEN1D, PEN2D), what typ of controller was used, other notes and then a number if this is a repeat of another test. This is much more useful when looking back at these logs later on. Before transferring the log file for processing you should record the wheel and propeller battery voltages in the header of the log file. The log file format is both human readable and can be parsed by MATALB. It was designed by the first RADA Senior Design Team and more information about the log files can be found [http://wikis.ece.iastate.edu/robotic-agriculture-data-acquisition/index.php/Data_Analysis_Tool here.] See he section below on measuring battery voltage below in order to get the best measurements for simulation of RADA.
=== Measuring Battery Voltages ===
The last thing that you need to do before simulating an experiment of the RADA platform is record the battery voltages for both the wheels and propellers. The wheel battery can be measured unloaded as there aren't large line losses between the battery and the H-bridges. The propeller battery voltage needs to be measured under load because the power cord running up the pendulum has significant line losses at the currents the propellers draw when in use. The battery voltages can be recorded in the log file for the test. Open the log file for the test you just completed (Use KWrite for Linux machines or Notepad++ for Windows machines). The first few lines of the log are the header. It should look like this:
#Constants pitch_P pitch_I pitch_D
#PIDValues 48000 18000 21000
#Constants roll_P roll_I roll_D
#PIDValues 48000 18000 21000
#Battery Vquad Vwheels
#Voltage
Follow the procedure for measuring the voltage of each battery and then record the voltage under the corresponding battery. Then save the log file and close out of your text editor and the test will be ready for processing. Recoding the battery voltages in this way makes it much easier to find if you need the value later. The final log file header should look like this once you are done
#Constants pitch_P pitch_I pitch_D
#PIDValues 48000 18000 21000
#Constants roll_P roll_I roll_D
#PIDValues 48000 18000 21000
#Battery Vquad Vwheels
#Voltage 14.44 8.257
==== Wheel Battery ====
#After test disconnect wheel battery from the system.
#Measure voltage of battery using multimeter.
[[Image:MeasureVwheel.jpg|800px]]
You can use the plug used for charging the 2-cell Lipos but make sure to connect the plug to the multimeter before connecting the battery and disconnect the battery before disconnecting the plug from the mulitmeter. It is generally the best practice to give the multimeter a few minutes to allow for the voltage measurement to stabilize as the battery measurement tends to be a little low right after the test. The multimeter will report data out to four decimal places it is best just to round to three decimal places for the wheel voltage.
==== Propeller Battery ====
#Setup code to run all four propellers at 50% throttle, uncomment the definition of ''mot50'' in main.cpp and compile the project.
#Power off propellers by turning off the switch to the ESCs.
#Connect multimeter to measure the voltage across one of the ESCs. This is done by using the power splitter cord.
##Connect one of the female XT60 connectors on the splitter to a male XT60 connector to banana connector cable.
##The banana connector connects to the hand held multimeter. The multimeter should be set to the 20VDC measurement setting.
##Next unplug one the ESCs' power connection.
##Reconnect the ESC to power through the two remain connectors on the splitter cable.
#Power on the propellers.
#Run the system at 50% throttle and measure the steady-state voltage during the test. The battery will slow the voltage decay significantly, meaning it will keep the same measurement for a few seconds.
#Stop the test and record the voltage in the log file. Make sure to disconnect the battery before removing the splitter cable.
{| class="wikitable" style="text-align:center"
|-
| [[Image:PowerSplitter.jpg|200px]]
| [[Image:QuadMultiCon.jpg |200px]]
| [[Image:QuadMultiSet.JPG |200px]]
| [[Image:QuadMeasESCcon.JPG|200px]]
|-
| Splitter cord.
| Connect splitter to multimeter.
| Settings for multimeter.
| Connecting ESC through splitter.
|}
The testing setup should look like the image below:
[[Image:QuadBattMeas.jpg|800px]]
== Post Processing and Simulation ==
Simulating a test of RADA starts with processing and storing the data. Then all of the parameters of the model are loaded in the MATLAB Workspace. Next, the Simulink file used for the simulation is opened and the length of the simulation is set to match the length of the actual test. The simulation is run and the simulation output is stored. Finally, the data should be plotted and compared.
=== Using the MATLAB Data Parsing Tool ===
In-depth discussion of how to use the log file parsing tool is described [http://wikis.ece.iastate.edu/robotic-agriculture-data-acquisition/index.php/Data_Analysis_Tool here.] It is suggested to use the version of the tool in the rada_resarch_project git repository Paul Uhing used for his Master's research. It can be found on CO3050-11 under the ucart account in the directory ''~/rada_research_project/DataAnalysiTool_omnicoor/Tool''. Simply open MATLAB and set the working directory to this file path. In the MATLAB Command Prompt run ''DataAnalysis''. A popup window should open up. Select the log file you want to process and wait for the tool to finish processing the file. Once this is complete there should be four structures in the MATLAB workspace.
-'''main''' : This contains all of the data extracted from the log file and the processing parameters used. main.expData contains two time structures: Time is used for the pendulum data and Eris_time is used for the ground vehicle data.
-'''X_ref''' : This contains the reference vector in m/s for x velocity that is fed into Simulink. This expedites the simulation setup process, this used to be done by hand.
-'''Y_ref''' : This contains the reference vector in m/s for y velocity that is fed into Simulink. This expedites the simulation setup process, this used to be done by hand.
-'''Yaw_ref''' : This contains the reference vector in radians for yaw that is fed into Simulink. This expedites the simulation setup process, this used to be done by hand. This one is new in case people start testing the system with heading changes but is not used in the current setup.
The first thing you should do is rename the main structure to the name you used for the log file. This is helpful for comparing multiple tests. Next, you will want to create two new variable ''Vquad_test'' and ''Vw_test''. In the MATLAB Command Prompt set the measured propeller voltage from the log file to ''Vquad_test'' and set the measured wheel voltage to ''Vw_test'' as this will be used by the simulation. Finally, if you did an open-loop test of the wheels create the variable ''Uol'' and set it to the open-loop wheel command used. Save all of these variables from the MATLAB workspace to a ''.mat'' file of the same name as the log file you extracted the data from and save it in the same directory as your RADA Simulink files. As of August 2nd, 2016 this directory is ''~/rada_research_project/MATLAB/RADA.''
=== Setting up the MATLAB Workspace for Simulation ===
Change your MATLAB directory to this directory. Then run the simulation setup files. Currently, you only need to run ''modelParams_smallWheels_RADA'' in the MATLAB Command Prompt. Next, open the Simulink file that contains the model of RADA controlled by the controller you tested.
-'''RADA_psiCtrl_v2_lqi_est.slx''' contains LQI, LQI+estimation, and LQG controller simulations.
-'''RADA_psiCtrl_v2.slx''' contains the PID controlled system.
-'''RADA_psiCtrl_v2_LQGsep.slx''' contains the subsystem LQG controlled system.
-'''RADA_psiCtrl_v2_LQGsep_ol.slx''' contains the simulation of the pendulum system controlled by an LQG and Eris controlled with open-loop commands.
Note all of the current (August 2nd, 2016) ''.slx'' files were created in MATLAB 2014b and will only work in MATLAB 2014b or newer. Then in the MATLAB Command Prompt type ''X_ref.time(end)'' exactly, don't add a semicolon, and hit enter. MATLAB will print the time of the last command in the X_ref structure. Set the end time of the simulation to this value and save your Simulink file.
=== Running Simulations and Storing Results ===
Before running the simulation make sure that the simulation is using the ''ode23t'' differential equations solver. This system is a moderately stiff system of differential and the ''ode45'' solver doesn't do well with these types of systems. When using ''ode23t'' is should only take a few minutes to run a 100+ second simulation while doing the same test using ''ode45'' could take 8 hours. While this is slow, it is also bad for your hard drive, as the simulation has to page between RAM and your computer's hard drive a lot.
Once this check is done, run the simulation. While it is running, check what the output structures variables are named for your RADA test system. Once the simulation is done, go to your MATLAB Workspace and select all 15 outputs for your simulation or your sub-simulation if you used '''RADA_psiCtrl_v2_lqi_est.slx'''. Save these 15 output structures to a ''.mat'' file named as the log file with _sim appended to the end of the name.
The 15 outputs are structures containing a time vector and then the data from the simulation sampled at 100 Hz and the units of this data are the SI units (ex: radians, m/s). There is one output structure for x velocity, y velocity, x body velocity, y body velocity, theta (pitch), phi (roll), psi (yaw), and one per actuator command (ex: the command sent to a wheel). Now you have all the data you can plot it.
=== Plotting Results ===
If you look at the ''DataSets'' folder below ''~/rada_research_project/MATLAB/RADA'' directory there are plenty of examples of how Paul Uhing compared simulation to test data. Generally, you should create an ''.m'' file with the same name as the log file this data was extracted from with _plot appended to the name.
Generally you can just copy and paste for ''RADA_LQG_compPID_plot.m'', ''RADA_PID_compLQG_plot.m'', ''RADA_LQG_sep_plot.m'', or ''RADA_LQG_sep_ol_plot.m'' files and rename the structures for your test.
These files create four figures. Figure 1 plots and compares the x velocity data in the first sub-figure and compares pitch (theta) data in the second sub-figure. Figure 2 does the same thing as Figure 1 but with y velocity and roll data. Figure 3 looks at the yaw data. Figure 4 looks at the sample period between UAV and ERIS packets from the camera system to check for periods of time with large packet drops.
You can follow a similar pattern to compare motor commands. Make sure that you compare Quad Motor 2 from the test data with Quad Motor 4 from simulation and vice versa because propellers 2 and 4 were switched in Eris's software compared to the Model.
That is all you need to know for testing RADA against the model.
c15b0f0e0c89254006ea5042e57cf3c5aca94a37
346
345
2016-09-26T18:53:54Z
Pfuhing
5
/* Testing Modes */
wikitext
text/x-wiki
This page will take you though setting up and testing RADA, retrieving the log file and other necessary data to run a simulation of that test and processing the data in MATLAB. Then actually running the simulation of RADA in Simulink. The initial setup and how to test the system can also be applied to demoing RADA.
== Setting Up a RADA Test ==
Testing RADA is not overly difficult once you get the hang of the steps to setup RADA. The following steps may seem like a long process to go from starting the testing process to having completed simulation and plotting of the test results but this whole test procedure (with the exception of battery charging) can be completed in about 15-20 minutes. These steps are meant to be as detailed as possible in order to help new users of RADA get up and running as quickly as possible.
'''<span style="color:red">NOTE: Always run RADA with at least 2 people!</span>''' The pendulum arm can crash into the ground if the network starts to drop packets and one person cannot give commands to RADA and spot the pendulum. This is a safety issue for both you and the RADA platform.
=== Charging Batteries ===
The lab currently uses mostly Hyperion batteries. We charge our batteries with a Hyperion EOS 1420i Net3 battery charger. For some general information about how to use this charger see [https://www.youtube.com/watch?v=-ox3EpzvsJ8 this video.]. In the lab we power this charger using the old Kepco Power supply because it is the only power supply that can supply enough current. Make sure that the power supply is set to an output voltage between 10.5V-29V.
{| class="wikitable" style="text-align:center"
|-
| [[Image:ChargerPowerSupplyOff.JPG|400px]]
| [[Image:ChargerPowerSuplyOn.JPG|400px]]
|-
| Kepco Power Supply off.
| Kepco Power Supply on with correct voltage supply range.
|}
The YouTube video link above should explain how to use the charger. RADA currently uses three different Lithium polymer (Lipo) batteries: 1600 mAh 2-cell Lipo for the wheels, 2600 mAh 2-cell Lipo for the electronics of Eris, and a 2600 mAh 4-cell Lipo for the propellers. The 1600 mAh 2-cell Lipo can be charged using memory slot 2 of the charger. The 2600 mAh 2-cell Lipos can be charged using memory slot 3 for fast charging and memory slot 4 for slower charging (use this if the battery voltage drops really low for 10-20 minutes then switch to fast charging). The 2600 mAh 4-cell Lipo can be charged using memory slot 8. The 1600 mAh 2-cell and 2600 mAh 4-cell generally charge in 10-20 minutes apiece while the 2600 mAh 2-cell generally take up to 70 minutes to charge fully.
=== Setting up the Camera System ===
The camera system is run on the windows computer CO3050-07. You can log into this computer using a local microcart username and password (not posted here for security reasons, but any one who works in the lab should know it). Once logged in, look for Tracking Tools in the start menu or look for the shortcut shown below:
[[Image:TrackingTools_shortcut.PNG|thumb|center|Tracking Tools shortcut]]
Once the program opens the screen should look something like this:
[[Image:NewTrackingTools.PNG|800px]]
In the Tracking Tools Quick Start pop up menu select Open Existing Project and then navigate to ''D:\Optitrack_Configuration'' (It should open to this directory by default) and select the most recent Tracking Tools project. It should have the naming scheme ''TrackingToolsProject YYYY-MM-DD timeStamp.ttp''. This is normally the most recently edited file when sorting by date modified. The most recent one as of August 1st, 2016 is ''TrackingToolsProject 2015-09-23 2.30pm.ttp''.
[[Image:OpeningProject.PNG|800px]]
You should notice that the cameras shown in the main project screen arrange themselves like the camera system configuration once the project has been opened. Now the constellations need to be loaded. This can be done by going to ''File->Open'' and another popup window will open. Navigate back to ''D:\Optitrack_Configuration'' (It should open to this directory by default) and select the most recently dated set of RADA trackables. They have the naming scheme ''RADA_entireSystem_M_D_YYYY.tra''. The most recent one as of August 1st, 2016 is ''RADA_entireSystem_7_8_2016.tra''.
[[Image:Opening_trackables.PNG|800px]]
Once the project and trackables are open, the cameras should appear in their constellation (square) and there should be two constellations under ''Project Explorer->Trackables''. One named UAV for the pendulum and one named ERIS for the ground vehicle. In order to get additional information about each constellation, left click on the the name of the desired trackable.
[[Image:SelectingUAV.PNG|800px]]
Once a trackable is selected more information about it is available in the ''Trackables'' Tab on the right side of the screen. For the current position and orientation look at the ''Real-Time Info'' sub-tab. The orientation of the system represented by pitch, roll, and yaw Euler Angles. The Euler Angles orientation is determined by the order the angles are solved for determine the result. Tracking Tools doesn't use the same angle calculation order as RADA uses to calculate the system orientation so unless the pendulum is held near vertical the orientation given is not correct. General speaking if the system is held so that at least 2/3 angles are near zero you can approximate the orientation seen by the system by swapping the yaw a pitch angles shown by the real time information tab.
[[Image:Uav_realTimeInfo.PNG|800px]]
Now we need to check to make sure the system is zeroed.
#Hold RADA so that the front of the ground robot (ERIS is facing the wall with the white boards (east)). The front side of Eris is labeled. If it isn't, the front is the side opposite the switches and the side with the trackable constellation on it.
#Make sure that the motor with the red motor mount is also facing the wall with the white boards.
#Make sure the quad system is aligned along Eris Axis by standing behind the system. If the system is aligned, you should be able to block the mounting bolts of the front propeller motor with the pole while facing the east wall.
#While holding the pendulum approximately vertical, see if the camera system reads zeros for the pendulum (UAV) pitch and roll (yaw and roll in ''Real-Time Info''). If yaw is off by a few degrees that is fine.
#Compare the yaw of the UAV to that of ERIS (Remember this is pitch in ''Real-Time Info''). If they are both near zero and within a few degrees and the pendulum's pitch/roll were also near zero then you are ready to use the camera system. Otherwise, go to the next step.
#You need to zero the pendulum.
##Align ERIS so it is near zero yaw first (eye ball it).
##Get a level and a friend. Have your friend use a level to ensure that the pendulum is level in both directions and hold it there.
##With the UAV constellation selected go to the ''Orientation'' tab (next to ''Real-Time Info'' tab) and click on ''Reset To Current Orientation'' button
##Now your friend can set the pendulum down and you can zero ERIS the same way.
#Save the new trackable orientation by going to ''File->Save Trackables...'' and save a file using the same naming conventions as the trackable file you opened earlier. Use the current data so you don't have to re-zero the system the next time you test.
[[Image:Uav_ResetOrientation.PNG|800px]]
=== Building Software ===
The development environment for running RADA is hosted on CO3050-11, a Linux Red Hat environment. This computer has a local ucart user name that you should use (the password isn't put here for security reasons). First, ensure that the RADA software is setup correctly for the test you want to run. To do this, you will need to open the main.cpp and logger.cpp files and make sure all of the compile time macros you want are defined correctly. All of the c++ files you should need to edit are in the directory ''~/Desktop/rada_research_project/ErisResearchCode/CppProjects/MainProgram_PacketLoss/src/Korebot'' Below are compiler macro options for main.cpp:
-'''H2ctrl''' : This will cause the system to enter H2 controller mode where the whole RADA system is controlled by an H2 controller.
-'''ssTracking''' : H2ctrl must also be defined for this macro to do anything. This macro will control using a tracking H2 controller. This controller doesn't have propeller velocity states so the controller makes use of the propellers.
-'''ssMotors''' : H2ctrl must also be defined for this macro to do anything. This macro will control the system using a H2 controller that contains propeller velocity states. This also causes the system to "Dance" because the propellers are slower than the wheels so the H2 controller will not use the propellers.
-'''ssDrop''' : Cause the system to go into packet drop controller mode. This mode allows controllers designed for lossy networks to be tested. Based off of other definitions how lossy the network is can be simulated. If nothing else is defined this controller becomes basically a H2 controller.
-'''drop10''' : Will put the packet drop mode into 10% loss mode and use a controller designed for 10% loss.
-'''drop30''' : Will put the packet drop mode into 30% loss mode and use a controller designed for 30% loss.
-'''drop50''' : Will put the packet drop mode into 50% loss mode and use a controller designed for 50% loss.
-'''mot50''' : This macro over-rides all other macros. If this is turned on the wheels will not run and the propellers will be run at 50% command. This is used for measuring the effective battery voltage seen by the ESCs. This is always run after a test.
-'''RADAlqi''' : This macro will cause the system to use an LQI controller on the whole system. The linear velocity states are calculated with no filter and the angular velocity states are calculated with filters.
-'''RADAlqi_est''' : This macro will cause the system to use an LQI controller on the whole system. A traditional estimator is used to estimate the states.
-'''rada_lqg''' : This macro will cause the entire system to be controlled by an LQG controller/estimator system.
-'''rada_split_lqg''' : This macro will cause the pendulum and ground robot to be controlled by their own LQG systems.
-'''rada_split_lqg_ol''' : This macro will cause the pendulum to be controlled by an LQG controller, the yaw of the ground robot to be controlled by a PID controller, and the ground robot linear velocities to be controlled with open-loop commands.
-'''yaw_off''' : This macro will cause the yaw control to be disabled on some controllers.
*'''accR''' : This macro will cause the PID linear velocity controllers to be given ramps to accelerate from one velocity to another instead of steps.
-'''posRamp''' : This macro will cause the linear velocities of RADA to be controlled by position PIDs with ramp reference instead of velocity commands.
-If no controller selection is made all controllers revert to PID controllers
All of these macros can be defined simply by uncommenting the corresponding define statement in main.cpp. The macros in the logger.cpp can be seen below:
-'''ssDrop''' : This macro puts the logger into packet drop controller mode and logs the correct values for the packet drop controllers.
-'''RADAlqi''' : This macro puts the logger into full system LQI controller logging mode.
-'''RADAlqi_est''' : This macro puts the logger into full system LQI controller plus estimator logging mode.
-'''rada_lqg''' : This puts the logger into full system LQG controller logging mode.
-'''rada_split_lqg''' : This macro causes the logger to log data about the subsystem LQG controllers.
-'''rada_split_lqg_ol''' : This cause the system to log data about the pendulum LQG system and the open-loop linear velocity commands.
-'''H2ctrl''' : This macro causes the logger to log data about the full system H2 controllers.
-If no logging mode is selected then the logger will default to logging PID data.
Because the system only calculates controllers for one set of controllers it is important to ensure that the logger is in the correct mode based off of what is defined in main.cpp. As of August 1st, 2016 the defines in main.cpp are not seen in logger.cpp.
Finally in a command prompt navigate to the driectroy: ''~/Desktop/rada_research_project/ErisResearchCode/CppProjects/MainProgram_PacketLoss''
Here just type: ''make''. The code will compile for your desired mode. For setting up a new development directory see [http://wikis.ece.iastate.edu/robotic-agriculture-data-acquisition/index.php/Setting_up_a_new_development_environment Setting up a new development environment] from the RADA Senior Design wiki.
[[Image:ComplingRADACode.png|800px]]
The complied executable code ends up in ''/home/shared/MainProject''. The ''/home/shared'' directory is setup as a network file share (NFS).
[[Image:ErisCompliedCode-config.png|800px]]
This service needs to be restarted when CO3050-11 is restarted. [http://wikis.ece.iastate.edu/robotic-agriculture-data-acquisition/index.php/Configuring_NFS_shares_for_the_robot Configure NFS shares for the robot] from the RADA Senior Design wiki. Be sure to use the new Linux install command in step six. Though I have found that even on a good strt the ''[ok]'' messages will still print.
=== Turning on RADA ===
Turning on Eris is fairly simple. Each system has its own battery. There is one for the wheels that plugs in at the front of Eris (opposite side of the switches), one for the electronics in the back of Eris (in between the switches), and one for the propellers that goes on top of Eris.
[[Image:ErisOnPhoto.jpg|800px]]
The wheel battery is normally 1600 mAh 2-cell Lipo but any 2-cell Lipo will work. The wheels are turned on by flipping the silver switch so the top points away from the system. The electronics normally use a 2600 mAh 2-cell Lipo. The electronics are turned on by flipping the green switch away from the system. It is important that you use EITHER the WIFI adapter OR hardwired Ethernet, because the VRPN may listen to the camera data broadcast over both connections which could cause problems. The propeller system is powered via a 2600 mAh 4-cell Lipo that connects to a power cable at the base of the pendulum. There is a switch to turn on the power to the propellers system. You will know it is on when the 1 on the switch is flush with the switch housing instead of sticking out. It takes about 30 seconds to a minute for Eris to boot up and start the networking connections. When the WIFI is plugged in, you will know it is ready when a blue light turns on, on the module.
=== Connecting to RADA ===
RADA is controlled through an SSH connection in a command prompt. This is not the one you compile the code from so that you can recompile for different setup without needing to close the connection. If you are using a WIFI connection, use the command ''ssh root@192.168.0.53''. If you are connected to Eris through a LAN connection use the command ''ssh root@192.168.0.54''. If the connection goes though you should be prompted for a password.
The password is ''rootme''.
[[Image:Ssh2Eris.png|800px]]
It is important to close the SSH connection before turning off Eris because the terminal you are using will hang up if you don't. You can close the connection by using the command ''exit''.
[[Image:ClosingSSH.png|800px]]
== Testing RADA ==
Now that you are connected to Eris you can run tests. The testing is started by a few different methods.
=== Running the First Test After Power Up ===
For the first test after powering on Eris, a few additional steps need to be completed in order to test the system. The FPGA motor controller needs to be programmed and Eris needs to connect to the NFS server running on CO3050-11. This is accomplished by running ''1_co3050-11.sh'', this shell script will setup the NFS, and load the bit file into the FPGA configuration memory. Then it retrieves the executable file from the NFS server ''/mnt/nfs/MainProject'' and runs the executable. Once the user exits the executable, the log file produced is copied from the ''~/Logs/YYYY_MM_DD_Day'' directory on Eris to ''/home/shared/MainProject/Logs/YYYY_MM_DD_Day'' on CO3050-11. When the folder for the current Eris date doesn't exist, it creates this directory in CO3050-11 and then removes the directory and log file from Eris. You may see a warning that when copying the log file Eris couldn't maintain the file permission settings. This is normal as Eris doesn't have the same access to the NSF server as it has to its own files. This date stamp uses the date on Eris, which is currently in June of 2008 as of August 2nd, 2016.
Before starting the test, it is best to have someone spotting the pendulum and holding it near vertical so that the pendulum doesn't have issues when entering a control mode.'''<span style="color:red"> Always ensure the pendulum is spotted by a second person when testing so you don't hurt yourself, others in the lab, or the RADA system.</span>''' Once the spotter is ready, run the shell script by using the command ''./1_co3050-11.sh'' in the terminal with the open SSH connection to Eris from the home, ''/root'', directory of Eris. When you run this script there will be a bunch of information printed out about the PIC bus and loading the bit file to configure the FPGA. You will know that RADA is ready for the test when it asks you to select a running mode. See the Testing Modes section below. This script can take a while to complete so beyond the first test after startup you don't need to run this script. See the Section about Running additional tests below.r
[[Image:StartingRADA initial.png|800px]]
=== Testing Modes ===
The RADA system has three testing modes: Robot Control Mode, Tuning Mode, and Box Step Mode. Additionally, you can exit the execution at any time by pressing the ''Esc'' key. Once the terminal asks you to chose a mode, you can use the following commands to enter the desired mode with a three-second delay or exit the program. You can also use these commands to switch between the modes.
-''v'' : Enters the pendulum PID tuning mode - this will only really work when using PIDs to control the pendulum.
-''b'' : Enter robot control mode - in this mode you can drive the robot around and the pendulum will try to stay vertical. This is the main mode used for testing the whole RADA system.
-''n'' : Enters box step mode - the pendulum will change its desired pitch and roll angles every 20 seconds and move in a box shape.
-''Esc'' : By hitting the escape key the program will exit the program.
You will almost always want to run Robot Control Mode as the other modes are legacy modes from when we initially built and tested RADA and only works with the pendulum PID controllers. There are also a few utility commands that can be used in all modes.
-''2'' : Resets I components of the Pitch/Roll PIDs and only the PIDs. IE: quad.pitch.PID_icomp=0 and quad.roll.PID_icomp=0;
-''m'' : Adds a marker to the Log file. This can be done if there is a problem or if you are starting a new test. This way you can find these times in the log file.
==== Robot Control Mode ====
In Robot control mode you can control the motion of Eris. For PID control of Eris or 1D state feedback system the directional commands command Eris body velocity were for full system and Eris system state feedback controllers control the global velocity. All of these keys only need to be pressed not held down.
-''w'' : Moves Eris forward (+x) at some velocity depending on the controller.
-''s'' : Moves Eris in reverse (-x) at some velocity depending on the controller.
-''d'' : Moves Eris in right (+y) at some velocity depending on the controller.
-''a'' : Moves Eris in left (-y) at some velocity depending on the controller.
-''p'' : Stops the motion of Eris (Set all velocity set points to zero). I.e. if you hit ''w'' then hit ''s'' then Eris will be moving in reverse.
-''y'' : Moves Eris forward and to the right (+x/+y) simultaneously at some velocity depending on the controller.
-''t'' : Moves Eris forward and to the left (+x/-y) simultaneously at some velocity depending on the controller.
-''i'' : Moves Eris reverse and to the right (-x/+y) simultaneously at some velocity depending on the controller.
-''y'' : Moves Eris reverse and to the left (-x/-y) simultaneously at some velocity depending on the controller.
-''e'' : Rotate Eris clockwise (+yaw) at some angular rate. This only worked when RADA used the closed-loop FPGA control of the wheels. There is currently no controllers that use this command.
-''q'' : Rotate Eris counter-clockwise (-yaw) at some angular rate. This only worked when RADA used the closed-loop FPGA control of the wheels. There is currently no controllers that use this command.
-''<'' : Increment Eris' desired heading 45 degrees counter-clockwise (-yaw).
-''>'' : Increment Eris' desired heading 45 degrees clockwise (+yaw).
-''7'' : Increments the pitch set point (+pitch).
-''4'' : Decrements the pitch set point (-pitch).
-''8'' : Increments the roll set point (+roll).
-''5'' : Decrements the roll set point (-roll).
==== Tuning Mode ====
Tuning mode allows you to tune the PID controllers for both pitch and roll. The UI commands here are also available in Box Step Mode.
-''1'' : Tune the Pitch PID.
-''3'' : Tune the Roll PID.
-''7'' : Increase proportional gain of PID being tuned.
-''4'' : Decrease proportional gain of PID being tuned.
-''8'' : Increase integral gain of PID being tuned.
-''5'' : Decrease integral gain of PID being tuned.
-''9'' : Increase derivative gain of PID being tuned.
-''6'' : Decrease derivative gain of PID being tuned.
-''i'' : Increase set point of PID being tuned.
-''k'' : Decrease set point of PID being tuned.
-''o'' : Increase integral windup term of PID being tuned. (Not used)
-''l'' : Decrease integral windup term of PID being tuned. (Not used)
==== Box Step Mode ====
Box step mode will automatically change the set points of the pendulum every 20 seconds. The case statement for this mode can be changed for 1D and 2D step modes. This mode allows the user to use the same commands as Tuning Mode.
=== Running Additional Tests ===
Once you have run one test with Eris on, it is unnecessary to configure the FPGA or connect to the NFS server again. This is what took much of the time in the initial setup. This is what the script ''3_start_eris.sh'' was developed for. It does everything that ''1_co3050-11.sh'' does but without reprogramming the FPGA or reconnecting to the NFS server. As a result, it is ready to test much quicker.
Before starting the test, it is best to have someone spotting the pendulum and holding it near vertical so that the pendulum doesn't have issues when entering a control mode.'''<span style="color:red"> Always ensure the pendulum is spotted by a second person when testing so you don't hurt yourself, others in the lab, or the RADA system.</span>''' Once you spotter is ready run the shell script by using the command ''./3_start_eris.sh'' in the terminal with the open SSH connection to Eris from the home, ''/root'', directory of Eris.
[[Image:StartingRADA2nd.png|800px]]
=== Locating and Retrieving Log Files ===
If you are only demoing the system, there is no need to go beyond this point. Once you are done with a test that you want to compare to the model you should retrieve the log file right away so you don't mix it up with other test. On CO3050-11 go to the dircetory ''/home/shared/MainProject/Logs'' using the file browser (you can do this in a terminal but it is easier from the file explorer). Once there, look for the folder that has been modified most recently as Eris date is normally out of sync with its date and time. Then look for the newest log file. Log files have the naming scheme ''log(hh.mm.ss).txt'' (ex. log(13.04.51).txt). This naming convention works well to ensure that no log file is over written but it isn't useful for describing what the test was conducted for. Copy this log to the Desktop or to a USB drive and rename it. A good method is to name the file something like ''RADA_ctrl_otherNote#.txt'', where Describes what system you tested (ex. RADA, RADA1D, PEN1D, PEN2D), what typ of controller was used, other notes and then a number if this is a repeat of another test. This is much more useful when looking back at these logs later on. Before transferring the log file for processing you should record the wheel and propeller battery voltages in the header of the log file. The log file format is both human readable and can be parsed by MATALB. It was designed by the first RADA Senior Design Team and more information about the log files can be found [http://wikis.ece.iastate.edu/robotic-agriculture-data-acquisition/index.php/Data_Analysis_Tool here.] See he section below on measuring battery voltage below in order to get the best measurements for simulation of RADA.
=== Measuring Battery Voltages ===
The last thing that you need to do before simulating an experiment of the RADA platform is record the battery voltages for both the wheels and propellers. The wheel battery can be measured unloaded as there aren't large line losses between the battery and the H-bridges. The propeller battery voltage needs to be measured under load because the power cord running up the pendulum has significant line losses at the currents the propellers draw when in use. The battery voltages can be recorded in the log file for the test. Open the log file for the test you just completed (Use KWrite for Linux machines or Notepad++ for Windows machines). The first few lines of the log are the header. It should look like this:
#Constants pitch_P pitch_I pitch_D
#PIDValues 48000 18000 21000
#Constants roll_P roll_I roll_D
#PIDValues 48000 18000 21000
#Battery Vquad Vwheels
#Voltage
Follow the procedure for measuring the voltage of each battery and then record the voltage under the corresponding battery. Then save the log file and close out of your text editor and the test will be ready for processing. Recoding the battery voltages in this way makes it much easier to find if you need the value later. The final log file header should look like this once you are done
#Constants pitch_P pitch_I pitch_D
#PIDValues 48000 18000 21000
#Constants roll_P roll_I roll_D
#PIDValues 48000 18000 21000
#Battery Vquad Vwheels
#Voltage 14.44 8.257
==== Wheel Battery ====
#After test disconnect wheel battery from the system.
#Measure voltage of battery using multimeter.
[[Image:MeasureVwheel.jpg|800px]]
You can use the plug used for charging the 2-cell Lipos but make sure to connect the plug to the multimeter before connecting the battery and disconnect the battery before disconnecting the plug from the mulitmeter. It is generally the best practice to give the multimeter a few minutes to allow for the voltage measurement to stabilize as the battery measurement tends to be a little low right after the test. The multimeter will report data out to four decimal places it is best just to round to three decimal places for the wheel voltage.
==== Propeller Battery ====
#Setup code to run all four propellers at 50% throttle, uncomment the definition of ''mot50'' in main.cpp and compile the project.
#Power off propellers by turning off the switch to the ESCs.
#Connect multimeter to measure the voltage across one of the ESCs. This is done by using the power splitter cord.
##Connect one of the female XT60 connectors on the splitter to a male XT60 connector to banana connector cable.
##The banana connector connects to the hand held multimeter. The multimeter should be set to the 20VDC measurement setting.
##Next unplug one the ESCs' power connection.
##Reconnect the ESC to power through the two remain connectors on the splitter cable.
#Power on the propellers.
#Run the system at 50% throttle and measure the steady-state voltage during the test. The battery will slow the voltage decay significantly, meaning it will keep the same measurement for a few seconds.
#Stop the test and record the voltage in the log file. Make sure to disconnect the battery before removing the splitter cable.
{| class="wikitable" style="text-align:center"
|-
| [[Image:PowerSplitter.jpg|200px]]
| [[Image:QuadMultiCon.jpg |200px]]
| [[Image:QuadMultiSet.JPG |200px]]
| [[Image:QuadMeasESCcon.JPG|200px]]
|-
| Splitter cord.
| Connect splitter to multimeter.
| Settings for multimeter.
| Connecting ESC through splitter.
|}
The testing setup should look like the image below:
[[Image:QuadBattMeas.jpg|800px]]
== Post Processing and Simulation ==
Simulating a test of RADA starts with processing and storing the data. Then all of the parameters of the model are loaded in the MATLAB Workspace. Next, the Simulink file used for the simulation is opened and the length of the simulation is set to match the length of the actual test. The simulation is run and the simulation output is stored. Finally, the data should be plotted and compared.
=== Using the MATLAB Data Parsing Tool ===
In-depth discussion of how to use the log file parsing tool is described [http://wikis.ece.iastate.edu/robotic-agriculture-data-acquisition/index.php/Data_Analysis_Tool here.] It is suggested to use the version of the tool in the rada_resarch_project git repository Paul Uhing used for his Master's research. It can be found on CO3050-11 under the ucart account in the directory ''~/rada_research_project/DataAnalysiTool_omnicoor/Tool''. Simply open MATLAB and set the working directory to this file path. In the MATLAB Command Prompt run ''DataAnalysis''. A popup window should open up. Select the log file you want to process and wait for the tool to finish processing the file. Once this is complete there should be four structures in the MATLAB workspace.
-'''main''' : This contains all of the data extracted from the log file and the processing parameters used. main.expData contains two time structures: Time is used for the pendulum data and Eris_time is used for the ground vehicle data.
-'''X_ref''' : This contains the reference vector in m/s for x velocity that is fed into Simulink. This expedites the simulation setup process, this used to be done by hand.
-'''Y_ref''' : This contains the reference vector in m/s for y velocity that is fed into Simulink. This expedites the simulation setup process, this used to be done by hand.
-'''Yaw_ref''' : This contains the reference vector in radians for yaw that is fed into Simulink. This expedites the simulation setup process, this used to be done by hand. This one is new in case people start testing the system with heading changes but is not used in the current setup.
The first thing you should do is rename the main structure to the name you used for the log file. This is helpful for comparing multiple tests. Next, you will want to create two new variable ''Vquad_test'' and ''Vw_test''. In the MATLAB Command Prompt set the measured propeller voltage from the log file to ''Vquad_test'' and set the measured wheel voltage to ''Vw_test'' as this will be used by the simulation. Finally, if you did an open-loop test of the wheels create the variable ''Uol'' and set it to the open-loop wheel command used. Save all of these variables from the MATLAB workspace to a ''.mat'' file of the same name as the log file you extracted the data from and save it in the same directory as your RADA Simulink files. As of August 2nd, 2016 this directory is ''~/rada_research_project/MATLAB/RADA.''
=== Setting up the MATLAB Workspace for Simulation ===
Change your MATLAB directory to this directory. Then run the simulation setup files. Currently, you only need to run ''modelParams_smallWheels_RADA'' in the MATLAB Command Prompt. Next, open the Simulink file that contains the model of RADA controlled by the controller you tested.
-'''RADA_psiCtrl_v2_lqi_est.slx''' contains LQI, LQI+estimation, and LQG controller simulations.
-'''RADA_psiCtrl_v2.slx''' contains the PID controlled system.
-'''RADA_psiCtrl_v2_LQGsep.slx''' contains the subsystem LQG controlled system.
-'''RADA_psiCtrl_v2_LQGsep_ol.slx''' contains the simulation of the pendulum system controlled by an LQG and Eris controlled with open-loop commands.
Note all of the current (August 2nd, 2016) ''.slx'' files were created in MATLAB 2014b and will only work in MATLAB 2014b or newer. Then in the MATLAB Command Prompt type ''X_ref.time(end)'' exactly, don't add a semicolon, and hit enter. MATLAB will print the time of the last command in the X_ref structure. Set the end time of the simulation to this value and save your Simulink file.
=== Running Simulations and Storing Results ===
Before running the simulation make sure that the simulation is using the ''ode23t'' differential equations solver. This system is a moderately stiff system of differential and the ''ode45'' solver doesn't do well with these types of systems. When using ''ode23t'' is should only take a few minutes to run a 100+ second simulation while doing the same test using ''ode45'' could take 8 hours. While this is slow, it is also bad for your hard drive, as the simulation has to page between RAM and your computer's hard drive a lot.
Once this check is done, run the simulation. While it is running, check what the output structures variables are named for your RADA test system. Once the simulation is done, go to your MATLAB Workspace and select all 15 outputs for your simulation or your sub-simulation if you used '''RADA_psiCtrl_v2_lqi_est.slx'''. Save these 15 output structures to a ''.mat'' file named as the log file with _sim appended to the end of the name.
The 15 outputs are structures containing a time vector and then the data from the simulation sampled at 100 Hz and the units of this data are the SI units (ex: radians, m/s). There is one output structure for x velocity, y velocity, x body velocity, y body velocity, theta (pitch), phi (roll), psi (yaw), and one per actuator command (ex: the command sent to a wheel). Now you have all the data you can plot it.
=== Plotting Results ===
If you look at the ''DataSets'' folder below ''~/rada_research_project/MATLAB/RADA'' directory there are plenty of examples of how Paul Uhing compared simulation to test data. Generally, you should create an ''.m'' file with the same name as the log file this data was extracted from with _plot appended to the name.
Generally you can just copy and paste for ''RADA_LQG_compPID_plot.m'', ''RADA_PID_compLQG_plot.m'', ''RADA_LQG_sep_plot.m'', or ''RADA_LQG_sep_ol_plot.m'' files and rename the structures for your test.
These files create four figures. Figure 1 plots and compares the x velocity data in the first sub-figure and compares pitch (theta) data in the second sub-figure. Figure 2 does the same thing as Figure 1 but with y velocity and roll data. Figure 3 looks at the yaw data. Figure 4 looks at the sample period between UAV and ERIS packets from the camera system to check for periods of time with large packet drops.
You can follow a similar pattern to compare motor commands. Make sure that you compare Quad Motor 2 from the test data with Quad Motor 4 from simulation and vice versa because propellers 2 and 4 were switched in Eris's software compared to the Model.
That is all you need to know for testing RADA against the model.
fe427fe26aec7589c4ea6b4e360e14a2f71da349
Controller
0
5
319
229
2016-08-28T21:32:02Z
Jnoronha
3
/* Initialize the PID's */ changed to SYNTAXHIGHLIGHT for code examples
wikitext
text/x-wiki
The Crazyflie platform is completely customizable when it comes to the control design. As long as the controller can be written in C or C++, we can implement it in the Platform. This applies to both the controllers run on the PC Client and the controllers run on the Firmware of the Crazyflie. Originally the only controllers in the Platform were Firmware PID's that controlled the angular position and rates of the Crazyflie for hand flight. The original controller layout can be seen here [[#Original PID Controllers (Angular Rotation)|Original PID's]].
Below you will find documentation on the different types of Controllers that have been applied to the platform, organized by their location in the Platform.
== Firmware ==
=== Original PID Controllers (Angular Rotation) ===
Directly on the Crazyflie Firmware there are 5 PID controllers as seen here:
[[Image:FirmwareOnlyPIDArchitecture.png|500px]]
The Pitch and Roll angular position PID's receive constant setpoints from some outside source (gamepad controller or automated controller). The outputs of those angular position controllers is then fed into the angular rate controllers as shown. This final output is then fed into the Motor Command block which converts the angular rate setpoints into motor commands.
----
===State Estimator (Not Implemented Yet)===
('''***NOT YET IMPLEMENTED***''')
Bitcraze is currently working on adding a state estimator and state-feedback controller onto the Firmware to handle control calculations instead of the PID.
The code is in place but the controller is not yet used as of '''7/13/16'''.
== PC Client ==
=== Client PID Controllers (Position and Yaw) ===
The first controller implemented on the Client were 4 PID controllers used to stabilize the Crazyflie's position in X, Y, and Z, and angular position in Yaw respectively. These PID's feed directly into the Firmware PID's as seen here:
[[Image:CompletePIDArchitectureFigure.png|500px]]
The controllers inside the red box are the original PID controllers located on the Firmware as shown above in the [[#Original PID Controllers (Angular Rotation)|Original PID's]].
====Initialize the PID's====
:1. To start we create a struct with all the necessary variables (code from ''pid.h''):
::<syntaxhighlight lang="cpp">
typedef struct
{
float desired; //< set point
float error; //< error
float prevError; //< previous error
float integ; //< integral
float deriv; //< derivative
float kp; //< proportional gain
float ki; //< integral gain
float kd; //< derivative gain
float outP; //< proportional output (debugging)
float outI; //< integral output (debugging)
float outD; //< derivative output (debugging)
float iLimit; //< integral limit
float iLimitLow; //< integral limit
float dt; //< delta-time dt
float angularLimit; //sets limit for how far Crazyflie can tip, to prevent flipping
float angularLimitLow; //^
float thrustLimit; //Sets upper limit for Thrust Output (60000?) **?
float thrustLimitLow; //Sets lower limit for thrust Output (10001)
} PidObject;
</syntaxhighlight>
:2. To simplify scaling up the code to multiple Crazyflies, we will create a <code> ControllerObject </code> that contains multiple PID structs as shown (code in ''controller.h''):
::<syntaxhighlight lang="cpp">
typedef struct
{
PidObject pidRoll;
PidObject pidPitch;
PidObject pidYaw;
PidObject pidX;
PidObject pidY;
PidObject pidZ;
bool isInit;
} ControllerObject;
</syntaxhighlight>
:3. Then we initialize the Objects to 0 at the start of each run (code in ''eris_vrpn.cpp''):
::<syntaxhighlight lang="cpp">
ControllerObject pidCtrl1 = { 0 }; // init all fields to zero
ControllerObject pidCtrl2 = { 0 }; // init all fields to zero
ControllerObject pidCtrl3 = { 0 }; // init all fields to zero
ControllerObject pidCtrl4 = { 0 }; // init all fields to zero
</syntaxhighlight>
:4. Then populate the PidObjects with the desired parameters (code in ''pid.c''):
::<syntaxhighlight lang="cpp">
void pidInit(PidObject* pid, const float desired, const float kp,
const float ki, const float kd, const float dt)
{
pid->error = 0;
pid->prevError = 0;
pid->integ = 0;
pid->deriv = 0;
pid->desired = desired;
pid->kp = kp;
pid->ki = ki;
pid->kd = kd;
pid->iLimit = DEFAULT_PID_INTEGRATION_LIMIT;
pid->iLimitLow = -DEFAULT_PID_INTEGRATION_LIMIT;
pid->angularLimit = DEFAULT_PID_ANGLE_OUTPUT;
pid->angularLimitLow = -DEFAULT_PID_ANGLE_OUTPUT;
pid->thrustLimit = DEFAULT_PID_HIGH_THRUST_LIMIT;
pid->thrustLimitLow = DEFAULT_PID_LOW_THRUST_LIMIT;
pid->dt = dt;
}
</syntaxhighlight>
Using the above function for each of the <code>PidObjects</code> inside of the <code>ControllerObject</code> below (code in ''controller.c''):
::<syntaxhighlight lang="cpp">
void controllerInit( ControllerObject * ctrl )
{
if(ctrl->isInit)
return;
pidInit(&ctrl->pidY, 0, PID_Y_KP, PID_Y_KI, PID_Y_KD, CAMERA_UPDATE_DT); //for Roll PID
pidInit(&ctrl->pidX, 0, PID_X_KP, PID_X_KI, PID_X_KD, CAMERA_UPDATE_DT); //for Pitch PID
pidInit(&ctrl->pidYaw, 0, PID_YAW_KP, PID_YAW_KI, PID_YAW_KD, CAMERA_UPDATE_DT);
pidInit(&ctrl->pidZ, 0, PID_Z_KP, PID_Z_KI, PID_Z_KD, CAMERA_UPDATE_DT);
pidSetIntegralLimit(&ctrl->pidY, PID_Y_INTEGRATION_LIMIT);
pidSetIntegralLimit(&ctrl->pidX, PID_X_INTEGRATION_LIMIT);
pidSetIntegralLimit(&ctrl->pidYaw, PID_YAW_INTEGRATION_LIMIT);
pidSetIntegralLimit(&ctrl->pidZ, PID_Z_INTEGRATION_LIMIT);
ctrl->isInit = true;
}
</syntaxhighlight>
'''Note:''' If we have multiple Crazyflies we need a <code>ControllerObject</code> for each Crazyflie (code in ''eris_vrpn.cpp'')
::<syntaxhighlight lang="cpp">
controllerResetAllPID( &pidCtrl1 );
controllerInit( &pidCtrl1 );
#endif
#if NUM_QUADS >= 2
controllerResetAllPID( &pidCtrl2 );
controllerInit( &pidCtrl2 );
#endif
#if NUM_QUADS >=3
controllerResetAllPID( &pidCtrl3 );
controllerInit( &pidCtrl3 );
#endif
#if NUM_QUADS >=4
controllerResetAllPID( &pidCtrl4 );
controllerInit( &pidCtrl4 );
#endif
</syntaxhighlight>
Now the initialization of the Controllers is complete.
====Calculating the PID's====
:1. Each loop we want to calculate the PID output (code in ''pid.c''):
<blockquote>
<code>
<pre>
float pidUpdateAngle(PidObject* pid, const float measured, const bool updateError) //**USED FOR ATTITUDE CONTROL
{
float output;
if(updateError)
{
pid->error = pid->desired - measured; //Calculates current error
}
pid->integ += pid->error * pid->dt; //Calculates integral term
if(pid->integ > pid->iLimit) //Checks that the integral term stays below the integral limit (anti-windup)
{
pid->integ = pid->iLimit;
}
else if(pid->integ < pid->iLimitLow)
{
pid->integ = pid->iLimitLow;
}
pid->deriv = (pid->error - pid->prevError) / pid->dt; //Calculates derivative term
pid->outP = pid->kp* pid->error;
pid->outI = pid->ki * pid->integ;
pid->outD = pid->kd * pid->deriv;
output = pid->outP + pid->outI + pid->outD; //Adds up all 3 calculated terms for output
if(output > pid->angularLimit) //Limits amount Crazyflie can tip
{
output = pid->angularLimit;
}
if(output < pid->angularLimitLow) //Limits amount Crazyflie can tip
{
output = pid->angularLimitLow;
}
pid->prevError = pid->error; //Stores the current error for next loop
return output;
}
</pre>
</code>
</blockquote>
::'''Note:''' There are 3 different versions of this Function (for Angle, Thrust, and Yaw) since each has different output limits.
:2. Using the function above, combine all PID calculations into one function (code in ''controller.c''):
<blockquote>
<code>
<pre>
void controllerCorrectAttitudePID(ControllerObject * ctrl,
float xPositionActual, float yPositionActual, float zPositionActual, float eulerYawActual, float xPositionDesired, float yPositionDesired,
float zPositionDesired, float eulerYawDesired, float* rollControlOutput, float* pitchControlOutput, float* yawControlOutput, float* thrustControlOutput)
{
pidSetDesired(&ctrl->pidX, xPositionDesired);
*pitchControlOutput = pidUpdateAngle(&ctrl->pidX, xPositionActual, false); //Originally true
pidSetDesired(&ctrl->pidY, yPositionDesired);
*rollControlOutput = pidUpdateAngle(&ctrl->pidY, yPositionActual, false); //Originally true
pidSetDesired(&ctrl->pidZ, zPositionDesired);
*thrustControlOutput = pidUpdateThrust(&ctrl->pidZ,zPositionActual, true);
float yawError;
pidSetDesired(&ctrl->pidYaw, eulerYawDesired);
yawError = eulerYawDesired - eulerYawActual;
if(yawError > 180.0) //Ensures Yaw error stays between -180 and 180 degrees
yawError -= 360.0;
else if(yawError < -180.0)
yawError += 360.0;
pidSetError(&ctrl->pidYaw, yawError);
*yawControlOutput = pidUpdateYaw(&ctrl->pidYaw, eulerYawActual, true); //originally false
}
</pre>
</code>
</blockquote>
:3. In each Callback, calculate the Controller outputs, assigned to pointer values <code>*rollControlOutput</code>, <code>*pitchControlOutput</code>, etc... (code in ''eris_vrpn.cpp''):
<blockquote>
<code>
<pre>
xError1 = xPositionDesired1 - xPosition1;
yError1 = yPositionDesired1 - yPosition1; //Calculates error externally
controllerSetXYError(&pidCtrl1, xError1, yError1);
controllerCorrectAttitudePID(&pidCtrl1, t.pos[0], t.pos[1], zPosition1, correctedYaw1,
xPositionDesired1, yPositionDesired1, zPositionDesired1,
yawDesired1, &rollControlOutput1, &pitchControlOutput1,
&yawControlOutput1, &thrustControlOutput1);
</pre>
</code>
</blockquote>
::'''Note 1:''' We calculate error externally for X and Y because certain swarm controllers need special setpoint modifiers (this way we can switch modes without effecting the default setpoint):
::'''Note 2:''' Swap out the Controller - all we need to do is create a similar function and replace ''controllerCorrectAttitudePID'' above
::'''Example:''' Follow Hand Mode Error (Crazyflie1 will have setpoint -0.5 m lower in X and +0.5 m higher in Y than your hand trackable):
<blockquote>
<code>
<pre>
...
xError1 = (xPositionHand - 0.5) - xPosition1;
yError1 = (yPositionHand + 0.5) - yPosition1;
controllerSetXYError(&pidCtrl1, xError1, yError1);
...
</pre>
</code>
</blockquote>
:4. Send Calculated Control Outputs to the Crazyflie via the Radio (code found in ''simple.cpp''):
<blockquote>
<code>
<pre>
RunCrazyflie(crRadio2, cflieCopter3, rollControlOutput3, pitchControlOutput3, yawControlOutput3, thrustControlOutput3);
</pre>
</code>
</blockquote>
::Where the ''RunCrazyflie'' function looks like this (code in ''simple.cpp''):
<blockquote>
<code>
<pre>
int RunCrazyflie(CCrazyRadio *crRadio, CCrazyflie *cflieCopter, float rollControl, float pitchControl, float yawControl, float thrustControl) {
//Timing Index Variables (**FOR TESTING ROUTINES**)
int i = 0;
while(cflieCopter->cycle()) {
//If Crazyflie is vertical kill motors, Crash Imminent
if(cflieCopter->roll() > 90){
cflieCopter->setThrust(10000);
}
else if(cflieCopter->roll() < -90){
cflieCopter->setThrust(10000);
}
else if(cflieCopter->pitch() > 90){
cflieCopter->setThrust(10000);
}
else if(cflieCopter->pitch() < -90){
cflieCopter->setThrust(10000);
}
//Otherwise Send Setpoints
else if(i < 1){ //i < 200000
cflieCopter->setThrust(thrustControl);
cflieCopter->setRoll(rollControl);
cflieCopter->setPitch(pitchControl);
cflieCopter->setYaw(-yawControl); //******SET TO NEGATIVE FOR CAMERA SYSTEM YAW BEING REVERSED!!!!****
i++;
}
else{
break;
}
}
return 0;
}
</pre>
</code>
</blockquote>
::'''IMPORTANT:''' This function contains the function <code>cflieCopter->cycle()</code> which is CRITICAL to maintaining communications with the Crazyflie. The ''cycle'' function initiates communications, sends setpoints, and must be called frequently otherwise the communications will timeout and the Crazyflie will stop as a precaution.
:5. Repeat steps 3 through 5 for each set of new location data...until Program END.
===Swapping Client Controller Type===
With the Swarm Platform we can plug any controller (that can be coded in C or C++) into the Client to control the Crazyflies.
In steps 1, 2, and 3 of the [[#Calculating the PID's|Calculating the PID's]] section, you can see the whole process of how we calculate the control output. To replace the PID with a different controller we can follow those steps but with our new controller. So as a general idea of the process we have:
('''Note:''' This depends heavily on how your controller works, this is generalized for a single input single output controller)
#Implement the New Controller Output Calculation in C as a function
#Create multiple instances of this controller calculation function (for each Degree of Freedom (DOF) you need to control) and combine them into a function to calculate all controllers with 1 function call ('''Note:''' This step is for ease of code use, NOT Required)
#In each Callback, call the function to Calculate the Controller output.
----
<center> '''Main Directory''' </center>
<center> [[Crazyflie Swarm|Crazyflie Swarm Home]] | [[PC Client Software]] | [[USB Radio]] | [[Firmware]] | [[FAQ]] </center>
<center> '''Modifications Directory''' </center>
<center> [[Controller]] | [[Logging]] | [[Keyboard Commands]] | [[USB Radio#Changing Radio Channel|Changing Radio Channel]] | [[Flight Modes]] | [[Callbacks]] | [[Adding a Crazyflie]] | [[Firmware]] </center>
db1974ad37eeb69b593ee9a14976e4916c27a665
320
319
2016-08-28T21:38:21Z
Jnoronha
3
changed to SYNTAX HIGHLIGHT
wikitext
text/x-wiki
The Crazyflie platform is completely customizable when it comes to the control design. As long as the controller can be written in C or C++, we can implement it in the Platform. This applies to both the controllers run on the PC Client and the controllers run on the Firmware of the Crazyflie. Originally the only controllers in the Platform were Firmware PID's that controlled the angular position and rates of the Crazyflie for hand flight. The original controller layout can be seen here [[#Original PID Controllers (Angular Rotation)|Original PID's]].
Below you will find documentation on the different types of Controllers that have been applied to the platform, organized by their location in the Platform.
== Firmware ==
=== Original PID Controllers (Angular Rotation) ===
Directly on the Crazyflie Firmware there are 5 PID controllers as seen here:
[[Image:FirmwareOnlyPIDArchitecture.png|500px]]
The Pitch and Roll angular position PID's receive constant setpoints from some outside source (gamepad controller or automated controller). The outputs of those angular position controllers is then fed into the angular rate controllers as shown. This final output is then fed into the Motor Command block which converts the angular rate setpoints into motor commands.
----
===State Estimator (Not Implemented Yet)===
('''***NOT YET IMPLEMENTED***''')
Bitcraze is currently working on adding a state estimator and state-feedback controller onto the Firmware to handle control calculations instead of the PID.
The code is in place but the controller is not yet used as of '''7/13/16'''.
== PC Client ==
=== Client PID Controllers (Position and Yaw) ===
The first controller implemented on the Client were 4 PID controllers used to stabilize the Crazyflie's position in X, Y, and Z, and angular position in Yaw respectively. These PID's feed directly into the Firmware PID's as seen here:
[[Image:CompletePIDArchitectureFigure.png|500px]]
The controllers inside the red box are the original PID controllers located on the Firmware as shown above in the [[#Original PID Controllers (Angular Rotation)|Original PID's]].
====Initialize the PID's====
:1. To start we create a struct with all the necessary variables (code from ''pid.h''):
::<syntaxhighlight lang="cpp">
typedef struct
{
float desired; //< set point
float error; //< error
float prevError; //< previous error
float integ; //< integral
float deriv; //< derivative
float kp; //< proportional gain
float ki; //< integral gain
float kd; //< derivative gain
float outP; //< proportional output (debugging)
float outI; //< integral output (debugging)
float outD; //< derivative output (debugging)
float iLimit; //< integral limit
float iLimitLow; //< integral limit
float dt; //< delta-time dt
float angularLimit; //sets limit for how far Crazyflie can tip, to prevent flipping
float angularLimitLow; //^
float thrustLimit; //Sets upper limit for Thrust Output (60000?) **?
float thrustLimitLow; //Sets lower limit for thrust Output (10001)
} PidObject;
</syntaxhighlight>
:2. To simplify scaling up the code to multiple Crazyflies, we will create a <code> ControllerObject </code> that contains multiple PID structs as shown (code in ''controller.h''):
::<syntaxhighlight lang="cpp">
typedef struct
{
PidObject pidRoll;
PidObject pidPitch;
PidObject pidYaw;
PidObject pidX;
PidObject pidY;
PidObject pidZ;
bool isInit;
} ControllerObject;
</syntaxhighlight>
:3. Then we initialize the Objects to 0 at the start of each run (code in ''eris_vrpn.cpp''):
::<syntaxhighlight lang="cpp">
ControllerObject pidCtrl1 = { 0 }; // init all fields to zero
ControllerObject pidCtrl2 = { 0 }; // init all fields to zero
ControllerObject pidCtrl3 = { 0 }; // init all fields to zero
ControllerObject pidCtrl4 = { 0 }; // init all fields to zero
</syntaxhighlight>
:4. Then populate the PidObjects with the desired parameters (code in ''pid.c''):
::<syntaxhighlight lang="cpp">
void pidInit(PidObject* pid, const float desired, const float kp,
const float ki, const float kd, const float dt)
{
pid->error = 0;
pid->prevError = 0;
pid->integ = 0;
pid->deriv = 0;
pid->desired = desired;
pid->kp = kp;
pid->ki = ki;
pid->kd = kd;
pid->iLimit = DEFAULT_PID_INTEGRATION_LIMIT;
pid->iLimitLow = -DEFAULT_PID_INTEGRATION_LIMIT;
pid->angularLimit = DEFAULT_PID_ANGLE_OUTPUT;
pid->angularLimitLow = -DEFAULT_PID_ANGLE_OUTPUT;
pid->thrustLimit = DEFAULT_PID_HIGH_THRUST_LIMIT;
pid->thrustLimitLow = DEFAULT_PID_LOW_THRUST_LIMIT;
pid->dt = dt;
}
</syntaxhighlight>
Using the above function for each of the <code>PidObjects</code> inside of the <code>ControllerObject</code> below (code in ''controller.c''):
::<syntaxhighlight lang="cpp">
void controllerInit( ControllerObject * ctrl )
{
if(ctrl->isInit)
return;
pidInit(&ctrl->pidY, 0, PID_Y_KP, PID_Y_KI, PID_Y_KD, CAMERA_UPDATE_DT); //for Roll PID
pidInit(&ctrl->pidX, 0, PID_X_KP, PID_X_KI, PID_X_KD, CAMERA_UPDATE_DT); //for Pitch PID
pidInit(&ctrl->pidYaw, 0, PID_YAW_KP, PID_YAW_KI, PID_YAW_KD, CAMERA_UPDATE_DT);
pidInit(&ctrl->pidZ, 0, PID_Z_KP, PID_Z_KI, PID_Z_KD, CAMERA_UPDATE_DT);
pidSetIntegralLimit(&ctrl->pidY, PID_Y_INTEGRATION_LIMIT);
pidSetIntegralLimit(&ctrl->pidX, PID_X_INTEGRATION_LIMIT);
pidSetIntegralLimit(&ctrl->pidYaw, PID_YAW_INTEGRATION_LIMIT);
pidSetIntegralLimit(&ctrl->pidZ, PID_Z_INTEGRATION_LIMIT);
ctrl->isInit = true;
}
</syntaxhighlight>
'''Note:''' If we have multiple Crazyflies we need a <code>ControllerObject</code> for each Crazyflie (code in ''eris_vrpn.cpp'')
::<syntaxhighlight lang="cpp">
controllerResetAllPID( &pidCtrl1 );
controllerInit( &pidCtrl1 );
#endif
#if NUM_QUADS >= 2
controllerResetAllPID( &pidCtrl2 );
controllerInit( &pidCtrl2 );
#endif
#if NUM_QUADS >=3
controllerResetAllPID( &pidCtrl3 );
controllerInit( &pidCtrl3 );
#endif
#if NUM_QUADS >=4
controllerResetAllPID( &pidCtrl4 );
controllerInit( &pidCtrl4 );
#endif
</syntaxhighlight>
Now the initialization of the Controllers is complete.
====Calculating the PID's====
:1. Each loop we want to calculate the PID output (code in ''pid.c''):
::<syntaxhighlight lang="cpp">
float pidUpdateAngle(PidObject* pid, const float measured, const bool updateError) //**USED FOR ATTITUDE CONTROL
{
float output;
if(updateError)
{
pid->error = pid->desired - measured; //Calculates current error
}
pid->integ += pid->error * pid->dt; //Calculates integral term
if(pid->integ > pid->iLimit) //Checks that the integral term stays below the integral limit (anti-windup)
{
pid->integ = pid->iLimit;
}
else if(pid->integ < pid->iLimitLow)
{
pid->integ = pid->iLimitLow;
}
pid->deriv = (pid->error - pid->prevError) / pid->dt; //Calculates derivative term
pid->outP = pid->kp* pid->error;
pid->outI = pid->ki * pid->integ;
pid->outD = pid->kd * pid->deriv;
output = pid->outP + pid->outI + pid->outD; //Adds up all 3 calculated terms for output
if(output > pid->angularLimit) //Limits amount Crazyflie can tip
{
output = pid->angularLimit;
}
if(output < pid->angularLimitLow) //Limits amount Crazyflie can tip
{
output = pid->angularLimitLow;
}
pid->prevError = pid->error; //Stores the current error for next loop
return output;
}
</syntaxhighlight>
::'''Note:''' There are 3 different versions of this Function (for Angle, Thrust, and Yaw) since each has different output limits.
:2. Using the function above, combine all PID calculations into one function (code in ''controller.c''):
::<syntaxhighlight lang="cpp">
void controllerCorrectAttitudePID(ControllerObject * ctrl,
float xPositionActual, float yPositionActual, float zPositionActual, float eulerYawActual, float xPositionDesired, float yPositionDesired,
float zPositionDesired, float eulerYawDesired, float* rollControlOutput, float* pitchControlOutput, float* yawControlOutput, float* thrustControlOutput)
{
pidSetDesired(&ctrl->pidX, xPositionDesired);
*pitchControlOutput = pidUpdateAngle(&ctrl->pidX, xPositionActual, false); //Originally true
pidSetDesired(&ctrl->pidY, yPositionDesired);
*rollControlOutput = pidUpdateAngle(&ctrl->pidY, yPositionActual, false); //Originally true
pidSetDesired(&ctrl->pidZ, zPositionDesired);
*thrustControlOutput = pidUpdateThrust(&ctrl->pidZ,zPositionActual, true);
float yawError;
pidSetDesired(&ctrl->pidYaw, eulerYawDesired);
yawError = eulerYawDesired - eulerYawActual;
if(yawError > 180.0) //Ensures Yaw error stays between -180 and 180 degrees
yawError -= 360.0;
else if(yawError < -180.0)
yawError += 360.0;
pidSetError(&ctrl->pidYaw, yawError);
*yawControlOutput = pidUpdateYaw(&ctrl->pidYaw, eulerYawActual, true); //originally false
}
</syntaxhighlight>
:3. In each Callback, calculate the Controller outputs, assigned to pointer values <code>*rollControlOutput</code>, <code>*pitchControlOutput</code>, etc... (code in ''eris_vrpn.cpp''):
::<syntaxhighlight lang="cpp">
xError1 = xPositionDesired1 - xPosition1;
yError1 = yPositionDesired1 - yPosition1; //Calculates error externally
controllerSetXYError(&pidCtrl1, xError1, yError1);
controllerCorrectAttitudePID(&pidCtrl1, t.pos[0], t.pos[1], zPosition1, correctedYaw1,
xPositionDesired1, yPositionDesired1, zPositionDesired1,
yawDesired1, &rollControlOutput1, &pitchControlOutput1,
&yawControlOutput1, &thrustControlOutput1);
</syntaxhighlight>
::'''Note 1:''' We calculate error externally for X and Y because certain swarm controllers need special setpoint modifiers (this way we can switch modes without effecting the default setpoint):
::'''Note 2:''' Swap out the Controller - all we need to do is create a similar function and replace ''controllerCorrectAttitudePID'' above
::'''Example:''' Follow Hand Mode Error (Crazyflie1 will have setpoint -0.5 m lower in X and +0.5 m higher in Y than your hand trackable):
::<syntaxhighlight lang="cpp">
...
xError1 = (xPositionHand - 0.5) - xPosition1;
yError1 = (yPositionHand + 0.5) - yPosition1;
controllerSetXYError(&pidCtrl1, xError1, yError1);
...
</syntaxhighlight>
:4. Send Calculated Control Outputs to the Crazyflie via the Radio (code found in ''simple.cpp''):
::<syntaxhighlight lang="cpp">
RunCrazyflie(crRadio2, cflieCopter3, rollControlOutput3, pitchControlOutput3, yawControlOutput3, thrustControlOutput3);
</syntaxhighlight>
::Where the ''RunCrazyflie'' function looks like this (code in ''simple.cpp''):
::<syntaxhighlight lang="cpp">
int RunCrazyflie(CCrazyRadio *crRadio, CCrazyflie *cflieCopter, float rollControl, float pitchControl, float yawControl, float thrustControl) {
//Timing Index Variables (**FOR TESTING ROUTINES**)
int i = 0;
while(cflieCopter->cycle()) {
//If Crazyflie is vertical kill motors, Crash Imminent
if(cflieCopter->roll() > 90){
cflieCopter->setThrust(10000);
}
else if(cflieCopter->roll() < -90){
cflieCopter->setThrust(10000);
}
else if(cflieCopter->pitch() > 90){
cflieCopter->setThrust(10000);
}
else if(cflieCopter->pitch() < -90){
cflieCopter->setThrust(10000);
}
//Otherwise Send Setpoints
else if(i < 1){ //i < 200000
cflieCopter->setThrust(thrustControl);
cflieCopter->setRoll(rollControl);
cflieCopter->setPitch(pitchControl);
cflieCopter->setYaw(-yawControl); //******SET TO NEGATIVE FOR CAMERA SYSTEM YAW BEING REVERSED!!!!****
i++;
}
else{
break;
}
}
return 0;
}
</syntaxhighlight>
::'''IMPORTANT:''' This function contains the function <code>cflieCopter->cycle()</code> which is CRITICAL to maintaining communications with the Crazyflie. The ''cycle'' function initiates communications, sends setpoints, and must be called frequently otherwise the communications will timeout and the Crazyflie will stop as a precaution.
:5. Repeat steps 3 through 5 for each set of new location data...until Program END.
===Swapping Client Controller Type===
With the Swarm Platform we can plug any controller (that can be coded in C or C++) into the Client to control the Crazyflies.
In steps 1, 2, and 3 of the [[#Calculating the PID's|Calculating the PID's]] section, you can see the whole process of how we calculate the control output. To replace the PID with a different controller we can follow those steps but with our new controller. So as a general idea of the process we have:
('''Note:''' This depends heavily on how your controller works, this is generalized for a single input single output controller)
#Implement the New Controller Output Calculation in C as a function
#Create multiple instances of this controller calculation function (for each Degree of Freedom (DOF) you need to control) and combine them into a function to calculate all controllers with 1 function call ('''Note:''' This step is for ease of code use, NOT Required)
#In each Callback, call the function to Calculate the Controller output.
----
<center> '''Main Directory''' </center>
<center> [[Crazyflie Swarm|Crazyflie Swarm Home]] | [[PC Client Software]] | [[USB Radio]] | [[Firmware]] | [[FAQ]] </center>
<center> '''Modifications Directory''' </center>
<center> [[Controller]] | [[Logging]] | [[Keyboard Commands]] | [[USB Radio#Changing Radio Channel|Changing Radio Channel]] | [[Flight Modes]] | [[Callbacks]] | [[Adding a Crazyflie]] | [[Firmware]] </center>
f1fc3f07ef83af4e6569bcdf08f096d97dd9e6ad
Distributed Autonomous and Networked Control Lab Wiki
0
1
321
48
2016-09-11T20:41:57Z
Jonessk
7
Added a schedule slot
wikitext
text/x-wiki
Welcome to the Distributed Autonomous and Networked Control Lab Wiki! Here you can find a wealth of information regarding the many projects we have running in the Lab.
Below are some of the projects we are working on:
'''
== Projects ==
'''
[[Crazyflie Swarm]]
[[Robotic Agriculture Data Acquisition (RADA)]]
[[MicroCART]]
[[Camera System and VRPN]]
If you can't find what you're looking for please feel free to contribute.
Consult the [http://meta.wikimedia.org/wiki/Help:Contents User's Guide] for information on using the wiki software.
== Lab Schedule ==
== Getting Started ==
* [http://www.mediawiki.org/wiki/Manual:Configuration_settings Configuration settings list]
* [http://www.mediawiki.org/wiki/Manual:FAQ MediaWiki FAQ]
* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce MediaWiki release mailing list]
5386eb9e63fed622def2bd8b8b032690c86b34c3
322
321
2016-09-11T20:56:52Z
Jonessk
7
Inserted basic scheduling table
wikitext
text/x-wiki
Welcome to the Distributed Autonomous and Networked Control Lab Wiki! Here you can find a wealth of information regarding the many projects we have running in the Lab.
Below are some of the projects we are working on:
'''
== Projects ==
'''
[[Crazyflie Swarm]]
[[Robotic Agriculture Data Acquisition (RADA)]]
[[MicroCART]]
[[Camera System and VRPN]]
If you can't find what you're looking for please feel free to contribute.
Consult the [http://meta.wikimedia.org/wiki/Help:Contents User's Guide] for information on using the wiki software.
== Lab Schedule ==
{| class="wikitable" style="text-align:center"
|+Reserved Lab Times
|-
! Time !! Monday !! Tuesday !! Wednesday !! Thursday !! Friday
|-
! 8am - 9am
| Open || Open || Open || Open || Open
|-
! 9am - 10am
| Open || Open || Open || Open || Open
|-
! 10am - 11am
| Open || Open || Open || Open || Open
|-
! 11am - 12pm
| Open || Open || Open || Open || Open
|-
! 12pm - 1pm
| Open || Open || Open || Open || Open
|-
! 1pm - 2pm
| Open || Open || Open || Open || Open
|-
! 2pm - 3pm
| Open || Open || Open || Open || Open
|-
! 3pm - 4pm
| Open || Open || Open || Open || Open
|-
! 4pm - 5pm
| RADA || RADA || RADA || Open || Open
|-
! 5pm - 6pm
| RADA || RADA || RADA || Open || Open
|-
! 6pm - 7pm
| 1Open || Open || Open || Open || Open
|-
! 7pm - 8pm
| Open || Open || Open || Open || Open
|}
== Getting Started ==
* [http://www.mediawiki.org/wiki/Manual:Configuration_settings Configuration settings list]
* [http://www.mediawiki.org/wiki/Manual:FAQ MediaWiki FAQ]
* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce MediaWiki release mailing list]
aa4e6410ac4bcd6d71d6dcb9670c93694d173cf9
323
322
2016-09-11T21:14:47Z
Jonessk
7
Formatting changes to schedule
wikitext
text/x-wiki
Welcome to the Distributed Autonomous and Networked Control Lab Wiki! Here you can find a wealth of information regarding the many projects we have running in the Lab.
Below are some of the projects we are working on:
'''
== Projects ==
'''
[[Crazyflie Swarm]]
[[Robotic Agriculture Data Acquisition (RADA)]]
[[MicroCART]]
[[Camera System and VRPN]]
If you can't find what you're looking for please feel free to contribute.
Consult the [http://meta.wikimedia.org/wiki/Help:Contents User's Guide] for information on using the wiki software.
== Lab Schedule ==
{| class="wikitable" style="text-align:center"
|+Reserved Lab Times
|-
! width="100"|Time !! width="100"|Monday !! width="100"|Tuesday !! width="100"|Wednesday !! width="100"|Thursday !! width="100"|Friday
|-
! 8am - 9am
| Open || Open || Open || Open || Open
|-
! 9am - 10am
| Open || Open || Open || Open || Open
|-
! 10am - 11am
| Open || Open || Open || Open || Open
|-
! 11am - 12pm
| Open || Open || Open || Open || Open
|-
! 12pm - 1pm
| Open || Open || Open || Open || Open
|-
! 1pm - 2pm
| Open || Open || Open || Open || Open
|-
! 2pm - 3pm
| Open || Open || Open || Open || Open
|-
! 3pm - 4pm
| Open || Open || Open || Open || Open
|-
! 4pm - 5pm
| style="background:teal"|RADA || style="background:teal"|RADA || style="background:teal"|RADA || Open || Open
|-
! 5pm - 6pm
| style="background:teal"|RADA || style="background:teal"|RADA || style="background:teal"|RADA || Open || Open
|-
! 6pm - 7pm
| 1Open || Open || Open || Open || Open
|-
! 7pm - 8pm
| Open || Open || Open || Open || Open
|}
== Getting Started ==
* [http://www.mediawiki.org/wiki/Manual:Configuration_settings Configuration settings list]
* [http://www.mediawiki.org/wiki/Manual:FAQ MediaWiki FAQ]
* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce MediaWiki release mailing list]
56c97d0d496e669b49397b57fa13f69b76a8302c
324
323
2016-09-11T21:15:13Z
Jonessk
7
/* Lab Schedule */
wikitext
text/x-wiki
Welcome to the Distributed Autonomous and Networked Control Lab Wiki! Here you can find a wealth of information regarding the many projects we have running in the Lab.
Below are some of the projects we are working on:
'''
== Projects ==
'''
[[Crazyflie Swarm]]
[[Robotic Agriculture Data Acquisition (RADA)]]
[[MicroCART]]
[[Camera System and VRPN]]
If you can't find what you're looking for please feel free to contribute.
Consult the [http://meta.wikimedia.org/wiki/Help:Contents User's Guide] for information on using the wiki software.
== Lab Schedule ==
{| class="wikitable" style="text-align:center"
|+Reserved Lab Times
|-
! width="100"|Time !! width="100"|Monday !! width="100"|Tuesday !! width="100"|Wednesday !! width="100"|Thursday !! width="100"|Friday
|-
! 8am - 9am
| Open || Open || Open || Open || Open
|-
! 9am - 10am
| Open || Open || Open || Open || Open
|-
! 10am - 11am
| Open || Open || Open || Open || Open
|-
! 11am - 12pm
| Open || Open || Open || Open || Open
|-
! 12pm - 1pm
| Open || Open || Open || Open || Open
|-
! 1pm - 2pm
| Open || Open || Open || Open || Open
|-
! 2pm - 3pm
| Open || Open || Open || Open || Open
|-
! 3pm - 4pm
| Open || Open || Open || Open || Open
|-
! 4pm - 5pm
| style="background:teal"|RADA || style="background:teal"|RADA || style="background:teal"|RADA || Open || Open
|-
! 5pm - 6pm
| style="background:teal"|RADA || style="background:teal"|RADA || style="background:teal"|RADA || Open || Open
|-
! 6pm - 7pm
| Open || Open || Open || Open || Open
|-
! 7pm - 8pm
| Open || Open || Open || Open || Open
|}
== Getting Started ==
* [http://www.mediawiki.org/wiki/Manual:Configuration_settings Configuration settings list]
* [http://www.mediawiki.org/wiki/Manual:FAQ MediaWiki FAQ]
* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce MediaWiki release mailing list]
0b8b4c2f77c32dd3f565e6ee3ac273cceabe037b
325
324
2016-09-15T16:46:01Z
Jonessk
7
wikitext
text/x-wiki
Welcome to the Distributed Autonomous and Networked Control Lab Wiki! Here you can find a wealth of information regarding the many projects we have running in the Lab.
Below are some of the projects we are working on:
'''
== Projects ==
'''
[[Crazyflie Swarm]]
[[Robotic Agriculture Data Acquisition (RADA)]]
[[MicroCART]]
[[Camera System and VRPN]]
If you can't find what you're looking for please feel free to contribute.
Consult the [http://meta.wikimedia.org/wiki/Help:Contents User's Guide] for information on using the wiki software.
== Lab Schedule ==
{| class="wikitable" style="text-align:center"
|+Reserved Lab Times
|-
! width="110"|Time !! width="110"|Monday !! width="110"|Tuesday !! width="110"|Wednesday !! width="110"|Thursday !! width="110"|Friday
|-
! 8am - 9am
| Open || Open || Open || Open || Open
|-
! 9am - 10am
| Open || Open || Open || Open || Open
|-
! 10am - 11am
| Open || Open || Open || Open || Open
|-
! 11am - 12pm
| Open || Open || Open || Open || Open
|-
! 12pm - 1pm
| Open || Open || Open || Open || Open
|-
! 1pm - 2pm
| Open || Open || Open || Open || Open
|-
! 2pm - 3pm
| Open || Open || Open || Open || Open
|-
! 3pm - 4pm
| Open || Open || Open || Open || Open
|-
! 4pm - 5pm
| style="background:orange"|CrazyFlie Meeting || style="background:teal"|RADA || style="background:teal"|RADA Meeting || Open || Open
|-
! 5pm - 6pm
| style="background:teal"|RADA || style="background:teal"|RADA || style="background:teal"|RADA || Open || Open
|-
! 6pm - 7pm
| Open || Open || Open || Open || Open
|-
! 7pm - 8pm
| Open || Open || Open || Open || Open
|}
== Getting Started ==
* [http://www.mediawiki.org/wiki/Manual:Configuration_settings Configuration settings list]
* [http://www.mediawiki.org/wiki/Manual:FAQ MediaWiki FAQ]
* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce MediaWiki release mailing list]
af383122049a2fafa439bba4752765b6381cf22f
326
325
2016-09-21T01:58:54Z
Snawerdt
8
wikitext
text/x-wiki
Welcome to the Distributed Autonomous and Networked Control Lab Wiki! Here you can find a wealth of information regarding the many projects we have running in the Lab.
Below are some of the projects we are working on:
'''
== Projects ==
'''
[[Crazyflie Swarm]]
[[Robotic Agriculture Data Acquisition (RADA)]]
[[MicroCART]]
[[Camera System and VRPN]]
If you can't find what you're looking for please feel free to contribute.
Consult the [http://meta.wikimedia.org/wiki/Help:Contents User's Guide] for information on using the wiki software.
== Lab Schedule ==
{| class="wikitable" style="text-align:center"
|+Reserved Lab Times
|-
! width="110"|Time !! width="110"|Monday !! width="110"|Tuesday !! width="110"|Wednesday !! width="110"|Thursday !! width="110"|Friday
|-
! 8am - 9am
| Open || Open || Open || Open || Open
|-
! 9am - 10am
| Open || Open || Open || Open || Open
|-
! 10am - 11am
| Open || Open || Open || Open || Open
|-
! 11am - 12pm
| Open || Open || Open || Open || Open
|-
! 12pm - 1pm
| Open || Open || Open || Open || Open
|-
! 1pm - 2pm
| Open || Open || Open || Open || Open
|-
! 2pm - 3pm
| Open || Open || Open || Open || Open
|-
! 3pm - 4pm
| Open || Open || Open || Open || Open
|-
! 4pm - 5pm
| style="background:orange"|CrazyFlie Meeting || style="background:teal"|RADA || style="background:teal"|RADA Meeting || Open || Open
|-
! 5pm - 6pm
| style="background:teal"|RADA || style="background:teal"|RADA || style="background:teal"|RADA || Open || Open
|-
! 6pm - 7pm
| Open || Open || Open || Open || Open
|-
! 7pm - 8pm
| Open || Open || Open || Open || Open
|-
! 8pm - 9pm
| Open || Open || Open || Open || Open
|-
! 9pm - 10pm
| Open || Open || Open || Open || Open
|}
== Getting Started ==
* [http://www.mediawiki.org/wiki/Manual:Configuration_settings Configuration settings list]
* [http://www.mediawiki.org/wiki/Manual:FAQ MediaWiki FAQ]
* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce MediaWiki release mailing list]
6f467e272bc2f006b5fe3f0b6d3eadf87d4af155
327
326
2016-09-21T02:04:03Z
Snawerdt
8
wikitext
text/x-wiki
Welcome to the Distributed Autonomous and Networked Control Lab Wiki! Here you can find a wealth of information regarding the many projects we have running in the Lab.
Below are some of the projects we are working on:
'''
== Projects ==
'''
[[Crazyflie Swarm]]
[[Robotic Agriculture Data Acquisition (RADA)]]
[[MicroCART]]
[[Camera System and VRPN]]
If you can't find what you're looking for please feel free to contribute.
Consult the [http://meta.wikimedia.org/wiki/Help:Contents User's Guide] for information on using the wiki software.
== Lab Schedule ==
{| class="wikitable" style="text-align:center"
|+Reserved Lab Times
|-
! width="110"|Time !! width="110"|Monday !! width="110"|Tuesday !! width="110"|Wednesday !! width="110"|Thursday !! width="110"|Friday
|-
! 8am - 9am
| Open || Open || Open || Open || Open
|-
! 9am - 10am
| Open || Open || Open || Open || Open
|-
! 10am - 11am
| Open || Open || Open || Open || Open
|-
! 11am - 12pm
| Open || Open || Open || Open || Open
|-
! 12pm - 1pm
| Open || Open || Open || Open || Open
|-
! 1pm - 2pm
| Open || style="background:green"|MicroCART Meeting || Open || Open || Open
|-
! 2pm - 3pm
| Open || Open || Open || Open || Open
|-
! 3pm - 4pm
| Open || Open || Open || style="background:green"|MicroCART || Open
|-
! 4pm - 5pm
| style="background:orange"|CrazyFlie Meeting || style="background:teal"|RADA || style="background:teal"|RADA Meeting || style="background:green"|MicroCART || style="background:green"|MicroCART
|-
! 5pm - 6pm
| style="background:teal"|RADA || style="background:teal"|RADA || style="background:teal"|RADA || Open || style="background:green"|MicroCART
|-
! 6pm - 7pm
| Open || Open || Open || Open || Open
|-
! 7pm - 8pm
| Open || Open || Open || Open || Open
|-
! 8pm - 9pm
| Open || Open || Open || Open || Open
|-
! 9pm - 10pm
| Open || Open || Open || Open || Open
|}
== Getting Started ==
* [http://www.mediawiki.org/wiki/Manual:Configuration_settings Configuration settings list]
* [http://www.mediawiki.org/wiki/Manual:FAQ MediaWiki FAQ]
* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce MediaWiki release mailing list]
031193229ddc90ee7ff8aec46ee1f432b4abf71f
342
327
2016-09-26T17:12:00Z
Coleb
9
/* Lab Schedule */
wikitext
text/x-wiki
Welcome to the Distributed Autonomous and Networked Control Lab Wiki! Here you can find a wealth of information regarding the many projects we have running in the Lab.
Below are some of the projects we are working on:
'''
== Projects ==
'''
[[Crazyflie Swarm]]
[[Robotic Agriculture Data Acquisition (RADA)]]
[[MicroCART]]
[[Camera System and VRPN]]
If you can't find what you're looking for please feel free to contribute.
Consult the [http://meta.wikimedia.org/wiki/Help:Contents User's Guide] for information on using the wiki software.
== Lab Schedule ==
{| class="wikitable" style="text-align:center"
|+Reserved Lab Times
|-
! width="110"|Time !! width="110"|Monday !! width="110"|Tuesday !! width="110"|Wednesday !! width="110"|Thursday !! width="110"|Friday
|-
! 8am - 9am
| Open || Open || Open || Open || Open
|-
! 9am - 10am
| Open || Open || Open || Open || Open
|-
! 10am - 11am
| Open || Open || Open || Open || Open
|-
! 11am - 12pm
| Open || style="background:orange"|CrazyFlie || Open || Open || Open
|-
! 12pm - 1pm
| Open || style="background:orange"|CrazyFlie|| Open || style="background:orange"|CrazyFlie || Open
|-
! 1pm - 2pm
| Open || style="background:green"|MicroCART Meeting || style="background:orange"|CrazyFlie || style="background:orange"|CrazyFlie || Open
|-
! 2pm - 3pm
| Open || Open ||style="background:orange"|CrazyFlie Meeting || style="background:orange"|CrazyFlie || Open
|-
! 3pm - 4pm
| Open || Open || Open || style="background:green"|MicroCART || Open
|-
! 4pm - 5pm
| style="background:orange"|CrazyFlie Meeting || style="background:teal"|RADA || style="background:teal"|RADA Meeting || style="background:green"|MicroCART || style="background:green"|MicroCART
|-
! 5pm - 6pm
| style="background:teal"|RADA || style="background:teal"|RADA || style="background:teal"|RADA || Open || style="background:green"|MicroCART
|-
! 6pm - 7pm
| Open || Open || Open || Open || Open
|-
! 7pm - 8pm
| Open || Open || Open || Open || Open
|-
! 8pm - 9pm
| Open || Open || Open || Open || Open
|-
! 9pm - 10pm
| Open || Open || Open || Open || Open
|}
== Getting Started ==
* [http://www.mediawiki.org/wiki/Manual:Configuration_settings Configuration settings list]
* [http://www.mediawiki.org/wiki/Manual:FAQ MediaWiki FAQ]
* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce MediaWiki release mailing list]
fb4b05c1add4d473da3f5808de6392ef80762325
343
342
2016-09-26T17:12:42Z
Coleb
9
/* Lab Schedule */
wikitext
text/x-wiki
Welcome to the Distributed Autonomous and Networked Control Lab Wiki! Here you can find a wealth of information regarding the many projects we have running in the Lab.
Below are some of the projects we are working on:
'''
== Projects ==
'''
[[Crazyflie Swarm]]
[[Robotic Agriculture Data Acquisition (RADA)]]
[[MicroCART]]
[[Camera System and VRPN]]
If you can't find what you're looking for please feel free to contribute.
Consult the [http://meta.wikimedia.org/wiki/Help:Contents User's Guide] for information on using the wiki software.
== Lab Schedule ==
{| class="wikitable" style="text-align:center"
|+Reserved Lab Times
|-
! width="110"|Time !! width="110"|Monday !! width="110"|Tuesday !! width="110"|Wednesday !! width="110"|Thursday !! width="110"|Friday
|-
! 8am - 9am
| Open || Open || Open || Open || Open
|-
! 9am - 10am
| Open || Open || Open || Open || Open
|-
! 10am - 11am
| Open || Open || Open || Open || Open
|-
! 11am - 12pm
| Open || style="background:orange"|CrazyFlie || Open || Open || Open
|-
! 12pm - 1pm
| Open || style="background:orange"|CrazyFlie|| Open || style="background:orange"|CrazyFlie || Open
|-
! 1pm - 2pm
| Open || style="background:green"|MicroCART Meeting || style="background:orange"|CrazyFlie || style="background:orange"|CrazyFlie || Open
|-
! 2pm - 3pm
| Open || Open ||style="background:orange"|CrazyFlie || style="background:orange"|CrazyFlie || Open
|-
! 3pm - 4pm
| Open || Open || style="background:orange"|CrazyFlie || style="background:green"|MicroCART || Open
|-
! 4pm - 5pm
| style="background:orange"|CrazyFlie Meeting || style="background:teal"|RADA || style="background:teal"|RADA Meeting || style="background:green"|MicroCART || style="background:green"|MicroCART
|-
! 5pm - 6pm
| style="background:teal"|RADA || style="background:teal"|RADA || style="background:teal"|RADA || Open || style="background:green"|MicroCART
|-
! 6pm - 7pm
| Open || Open || Open || Open || Open
|-
! 7pm - 8pm
| Open || Open || Open || Open || Open
|-
! 8pm - 9pm
| Open || Open || Open || Open || Open
|-
! 9pm - 10pm
| Open || Open || Open || Open || Open
|}
== Getting Started ==
* [http://www.mediawiki.org/wiki/Manual:Configuration_settings Configuration settings list]
* [http://www.mediawiki.org/wiki/Manual:FAQ MediaWiki FAQ]
* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce MediaWiki release mailing list]
58473be9c24f8992845300861999c12460e56695
347
343
2016-09-26T22:02:17Z
Coleb
9
/* Lab Schedule */
wikitext
text/x-wiki
Welcome to the Distributed Autonomous and Networked Control Lab Wiki! Here you can find a wealth of information regarding the many projects we have running in the Lab.
Below are some of the projects we are working on:
'''
== Projects ==
'''
[[Crazyflie Swarm]]
[[Robotic Agriculture Data Acquisition (RADA)]]
[[MicroCART]]
[[Camera System and VRPN]]
If you can't find what you're looking for please feel free to contribute.
Consult the [http://meta.wikimedia.org/wiki/Help:Contents User's Guide] for information on using the wiki software.
== Lab Schedule ==
{| class="wikitable" style="text-align:center"
|+Reserved Lab Times
|-
! width="110"|Time !! width="110"|Monday !! width="110"|Tuesday !! width="110"|Wednesday !! width="110"|Thursday !! width="110"|Friday
|-
! 8am - 9am
| Open || Open || Open || Open || Open
|-
! 9am - 10am
| Open || Open || Open || Open || Open
|-
! 10am - 11am
| Open || style="background:orange"|CrazyFlie || Open || Open || Open
|-
! 11am - 12pm
| Open || style="background:orange"|CrazyFlie || Open || Open || Open
|-
! 12pm - 1pm
| Open || style="background:orange"|CrazyFlie|| Open || style="background:orange"|CrazyFlie || Open
|-
! 1pm - 2pm
| Open || style="background:green"|MicroCART Meeting || style="background:orange"|CrazyFlie || style="background:orange"|CrazyFlie || Open
|-
! 2pm - 3pm
| Open || Open ||style="background:orange"|CrazyFlie || style="background:orange"|CrazyFlie || Open
|-
! 3pm - 4pm
| Open || Open || style="background:orange"|CrazyFlie || style="background:green"|MicroCART || Open
|-
! 4pm - 5pm
| style="background:orange"|CrazyFlie Meeting || style="background:teal"|RADA || style="background:teal"|RADA Meeting || style="background:green"|MicroCART || style="background:green"|MicroCART
|-
! 5pm - 6pm
| style="background:teal"|RADA || style="background:teal"|RADA || style="background:teal"|RADA || Open || style="background:green"|MicroCART
|-
! 6pm - 7pm
| Open || Open || Open || Open || Open
|-
! 7pm - 8pm
| Open || Open || Open || Open || Open
|-
! 8pm - 9pm
| Open || Open || Open || Open || Open
|-
! 9pm - 10pm
| Open || Open || Open || Open || Open
|}
== Getting Started ==
* [http://www.mediawiki.org/wiki/Manual:Configuration_settings Configuration settings list]
* [http://www.mediawiki.org/wiki/Manual:FAQ MediaWiki FAQ]
* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce MediaWiki release mailing list]
a0d335e0f412f7ebd8fa1ee959f3b67a2a6eda6b
348
347
2016-10-03T20:07:36Z
Jonessk
7
/* Lab Schedule */
wikitext
text/x-wiki
Welcome to the Distributed Autonomous and Networked Control Lab Wiki! Here you can find a wealth of information regarding the many projects we have running in the Lab.
Below are some of the projects we are working on:
'''
== Projects ==
'''
[[Crazyflie Swarm]]
[[Robotic Agriculture Data Acquisition (RADA)]]
[[MicroCART]]
[[Camera System and VRPN]]
If you can't find what you're looking for please feel free to contribute.
Consult the [http://meta.wikimedia.org/wiki/Help:Contents User's Guide] for information on using the wiki software.
== Lab Schedule ==
{| class="wikitable" style="text-align:center"
|+Reserved Lab Times
|-
! width="110"|Time !! width="110"|Monday !! width="110"|Tuesday !! width="110"|Wednesday !! width="110"|Thursday !! width="110"|Friday
|-
! 8am - 9am
| Open || Open || Open || Open || Open
|-
! 9am - 10am
| Open || Open || Open || Open || Open
|-
! 10am - 11am
| Open || style="background:orange"|CrazyFlie || Open || Open || Open
|-
! 11am - 12pm
| Open || style="background:orange"|CrazyFlie || Open || Open || Open
|-
! 12pm - 1pm
| Open || style="background:orange"|CrazyFlie|| Open || style="background:orange"|CrazyFlie || Open
|-
! 1pm - 2pm
| Open || style="background:green"|MicroCART Meeting || style="background:orange"|CrazyFlie || style="background:orange"|CrazyFlie || Open
|-
! 2pm - 3pm
| Open || Open ||style="background:orange"|CrazyFlie || style="background:orange"|CrazyFlie || Open
|-
! 3pm - 4pm
| Open || Open || style="background:orange"|CrazyFlie || style="background:green"|MicroCART || Open
|-
! 4pm - 5pm
| style="background:orange"|CrazyFlie Meeting || style="background:teal"|RADA || style="background:teal"|RADA Meeting || style="background:green"|MicroCART || style="background:green"|MicroCART
|-
! 5pm - 6pm
| style="background:teal"|RADA || style="background:teal"|RADA || style="background:teal"|RADA || Open || style="background:green"|MicroCART
|-
! 6pm - 7pm
| style="background:teal"|RADA || style="background:teal"|RADA || style="background:teal"|RADA || Open || Open
|-
! 7pm - 8pm
| Open || Open || Open || Open || Open
|-
! 8pm - 9pm
| Open || Open || Open || Open || Open
|-
! 9pm - 10pm
| Open || Open || Open || Open || Open
|}
== Getting Started ==
* [http://www.mediawiki.org/wiki/Manual:Configuration_settings Configuration settings list]
* [http://www.mediawiki.org/wiki/Manual:FAQ MediaWiki FAQ]
* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce MediaWiki release mailing list]
0bf0b39982da2c0210754d792de553a13be91238
349
348
2016-10-07T05:16:02Z
Jonessk
7
wikitext
text/x-wiki
Welcome to the Distributed Autonomous and Networked Control Lab Wiki! Here you can find a wealth of information regarding the many projects we have running in the Lab.
Below are some of the projects we are working on:
'''
== Projects ==
'''
[[Crazyflie Swarm]]
[[Robotic Agriculture Data Acquisition (RADA)]]
[[MicroCART]]
[[Camera System and VRPN]]
If you can't find what you're looking for please feel free to contribute.
Consult the [http://meta.wikimedia.org/wiki/Help:Contents User's Guide] for information on using the wiki software.
== Lab Schedule ==
{| class="wikitable" style="text-align:center"
|+Reserved Lab Times
|-
! width="130"|Time !! width="130"|Monday !! width="130"|Tuesday !! width="130"|Wednesday !! width="130"|Thursday !! width="130"|Friday
|-
! 8am - 9am
| Open || Open || Open || Open || Open
|-
! 9am - 10am
| Open || Open || Open || Open || Open
|-
! 10am - 11am
| Open || style="background:orange"|CrazyFlie || Open || Open || Open
|-
! 11am - 12pm
| Open || style="background:orange"|CrazyFlie || Open || Open || Open
|-
! 12pm - 1pm
| Open || style="background:orange"|CrazyFlie|| Open || style="background:orange"|CrazyFlie || Open
|-
! 1pm - 2pm
| Open || style="background:green"|MicroCART Meeting || style="background:orange"|CrazyFlie || style="background:orange"|CrazyFlie || Open
|-
! 2pm - 3pm
| Open || Open ||style="background:orange"|CrazyFlie || style="background:orange"|CrazyFlie || Open
|-
! 3pm - 4pm
| Open || Open || style="background:orange"|CrazyFlie || style="background:green"|MicroCART || Open
|-
! 4pm - 5pm
| style="background:orange"|CrazyFlie Meeting || style="background:teal"|RADA || style="background:teal"|RADA Meeting || style="background:green"|MicroCART || style="background:green"|MicroCART
|-
! 5pm - 6pm
| style="background:teal"|RADA || style="background:teal"|RADA || style="background:teal"|RADA || Open || style="background:green"|MicroCART
|-
! 6pm - 7pm
| style="background:teal"|RADA || style="background:teal"|RADA || style="background:teal"|RADA || Open || Open
|-
! 7pm - 8pm
| Open || Open || Open || Open || Open
|-
! 8pm - 9pm
| Open || Open || Open || Open || Open
|-
! 9pm - 10pm
| Open || Open || Open || Open || Open
|}
== Getting Started ==
* [http://www.mediawiki.org/wiki/Manual:Configuration_settings Configuration settings list]
* [http://www.mediawiki.org/wiki/Manual:FAQ MediaWiki FAQ]
* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce MediaWiki release mailing list]
6d1e41290419fc455e438e19e82f812e416055e8
350
349
2016-10-13T16:01:44Z
Imciner2
6
wikitext
text/x-wiki
Welcome to the Distributed Autonomous and Networked Control Lab Wiki! Here you can find a wealth of information regarding the many projects we have running in the Lab.
Below are some of the projects we are working on:
'''
== Projects ==
'''
[[Crazyflie Swarm]]
[[Robotic Agriculture Data Acquisition (RADA)]]
[[MicroCART]]
[[Camera System and VRPN]]
'''
== Lab-Wide Information ==
[[Physical Parameters]] - Physical parameters for systems in the laboratory
If you can't find what you're looking for please feel free to contribute.
Consult the [http://meta.wikimedia.org/wiki/Help:Contents User's Guide] for information on using the wiki software.
== Lab Schedule ==
{| class="wikitable" style="text-align:center"
|+Reserved Lab Times
|-
! width="130"|Time !! width="130"|Monday !! width="130"|Tuesday !! width="130"|Wednesday !! width="130"|Thursday !! width="130"|Friday
|-
! 8am - 9am
| Open || Open || Open || Open || Open
|-
! 9am - 10am
| Open || Open || Open || Open || Open
|-
! 10am - 11am
| Open || style="background:orange"|CrazyFlie || Open || Open || Open
|-
! 11am - 12pm
| Open || style="background:orange"|CrazyFlie || Open || Open || Open
|-
! 12pm - 1pm
| Open || style="background:orange"|CrazyFlie|| Open || style="background:orange"|CrazyFlie || Open
|-
! 1pm - 2pm
| Open || style="background:green"|MicroCART Meeting || style="background:orange"|CrazyFlie || style="background:orange"|CrazyFlie || Open
|-
! 2pm - 3pm
| Open || Open ||style="background:orange"|CrazyFlie || style="background:orange"|CrazyFlie || Open
|-
! 3pm - 4pm
| Open || Open || style="background:orange"|CrazyFlie || style="background:green"|MicroCART || Open
|-
! 4pm - 5pm
| style="background:orange"|CrazyFlie Meeting || style="background:teal"|RADA || style="background:teal"|RADA Meeting || style="background:green"|MicroCART || style="background:green"|MicroCART
|-
! 5pm - 6pm
| style="background:teal"|RADA || style="background:teal"|RADA || style="background:teal"|RADA || Open || style="background:green"|MicroCART
|-
! 6pm - 7pm
| style="background:teal"|RADA || style="background:teal"|RADA || style="background:teal"|RADA || Open || Open
|-
! 7pm - 8pm
| Open || Open || Open || Open || Open
|-
! 8pm - 9pm
| Open || Open || Open || Open || Open
|-
! 9pm - 10pm
| Open || Open || Open || Open || Open
|}
== Getting Started ==
* [http://www.mediawiki.org/wiki/Manual:Configuration_settings Configuration settings list]
* [http://www.mediawiki.org/wiki/Manual:FAQ MediaWiki FAQ]
* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce MediaWiki release mailing list]
aa2e49dba8aec2e45a65b9e19bec5cc7fc86f3f3
File:ErisOnPhoto.jpg
6
62
334
216
2016-09-21T23:17:53Z
Jonessk
7
Jonessk uploaded a new version of [[File:ErisOnPhoto.jpg]]
wikitext
text/x-wiki
da39a3ee5e6b4b0d3255bfef95601890afd80709
335
334
2016-09-21T23:22:02Z
Jonessk
7
Jonessk uploaded a new version of [[File:ErisOnPhoto.jpg]]
wikitext
text/x-wiki
da39a3ee5e6b4b0d3255bfef95601890afd80709
336
335
2016-09-21T23:23:10Z
Jonessk
7
Jonessk uploaded a new version of [[File:ErisOnPhoto.jpg]]
wikitext
text/x-wiki
da39a3ee5e6b4b0d3255bfef95601890afd80709
Physical Parameters
0
83
351
2016-10-13T16:06:05Z
Imciner2
6
Added motor information
wikitext
text/x-wiki
== Motor/Propeller Information ==
{| class="wikitable"
|+Motor Information
|-
|
|Kv (RPM)
|Kv (rad/sec)
|Kq (rad/sec)
|If (A)
|Rm (Ohms)
|-
|DJI Opto 30A Old Motor
|920
|96.3422
|96.3422
|0.422
|0.243
|-
|DJI Opto 30A New Motor
|920
|96.3422
|96.3422
|0.511
|TBD
|}
03ecd6a99f1ea8049c801ad9c9d24fefa45ec58d
352
351
2016-10-13T16:12:54Z
Imciner2
6
Added propeller information
wikitext
text/x-wiki
== Motor/Propeller Information ==
{| class="wikitable"
|+Motor Information
|-
|
|Kv (RPM)
|Kv (rad/sec)
|Kq (rad/sec)
|If (A)
|Rm (Ohms)
|-
|DJI Opto 30A Old Motor
|920
|96.3422
|96.3422
|0.422
|0.243
|-
|DJI Opto 30A New Motor
|920
|96.3422
|96.3422
|0.511
|TBD
|}
{| class="wikitable"
|+Propeller Information
|-
|
|Kt (kgm/rad^2)
|Kd (kgm^2/rad^2)
|-
|DJI 8045 8in
|2.3765E-07
|7.9008E-06
|-
|DJI 9443 9in
|9.5705E-06
|TBD
|-
|Carbon Fiber 9in
|1.2364E-05
|2.9011E-07
|-
|DJI 1045 10in
|1.1325E-05
|3.5388E-07
|}
e67b603f38c24d19028d3c6e7efa35cccd395fbc
353
352
2016-10-13T16:23:51Z
Imciner2
6
Added system information
wikitext
text/x-wiki
== Motor Information ==
{| class="wikitable"
|+Motor Information
|-
|
|Kv (RPM)
|Kv (rad/sec)
|Kq (rad/sec)
|If (A)
|Rm (Ohms)
|-
|DJI 2212/920 Old Motor
|920
|96.3422
|96.3422
|0.422
|0.243
|-
|DJI 2212/920 New Motor
|920
|96.3422
|96.3422
|0.511
|TBD
|}
== Propeller Information ==
{| class="wikitable"
|+Propeller Information
|-
|
|Kt (kgm/rad^2)
|Kd (kgm^2/rad^2)
|-
|DJI 8045 8in
|2.3765e-07
|7.9008e-06
|-
|DJI 9443 9in
|9.5705e-06
|TBD
|-
|Carbon Fiber 9in
|1.2364e-05
|2.9011e-07
|-
|DJI 1045 10in
|1.1325e-05
|3.5388e-07
|}
== Motor & Propeller System Information ==
{| class="wikitable"
|+Propeller Information
|-
|
|Tau (sec)
|Jr (kgm^2)
|-
|DJI 2212/920 New w/ 9445 Propeller & Standard ESC
|0.09
|TBD
|-
|DJI 2212/920 Old w/ 8045 Propeller & Standard ESC
|0.12
|5.3204e-05
|-
|DJI 2212/920 Old w/ 1045 Propeller & Standard ESC
|0.14
|6.2071e-05
|-
|DJI 2212/920 Old w/ 10in Carbon Fiber Propeller & Standard ESC
|0.24
|1.0641e-04
|}
d0be23bd8d45c24dd0f7062091ae8b18377f2d55
354
353
2016-10-13T16:25:25Z
Imciner2
6
/* Motor & Propeller System Information */
wikitext
text/x-wiki
== Motor Information ==
{| class="wikitable"
|+Motor Information
|-
|
|Kv (RPM)
|Kv (rad/sec)
|Kq (rad/sec)
|If (A)
|Rm (Ohms)
|-
|DJI 2212/920 Old Motor
|920
|96.3422
|96.3422
|0.422
|0.243
|-
|DJI 2212/920 New Motor
|920
|96.3422
|96.3422
|0.511
|TBD
|}
== Propeller Information ==
{| class="wikitable"
|+Propeller Information
|-
|
|Kt (kgm/rad^2)
|Kd (kgm^2/rad^2)
|-
|DJI 8045 8in
|2.3765e-07
|7.9008e-06
|-
|DJI 9443 9in
|9.5705e-06
|TBD
|-
|Carbon Fiber 9in
|1.2364e-05
|2.9011e-07
|-
|DJI 1045 10in
|1.1325e-05
|3.5388e-07
|}
== Motor & Propeller System Information ==
{| class="wikitable"
|+Propeller Information
|-
|
|Tau (sec)
|Jr (kgm^2)
|-
|DJI 2212/920 New w/ 9445 Propeller & New DJI Opto 30A ESC
|0.09
|TBD
|-
|DJI 2212/920 Old w/ 8045 Propeller & Old DJI Opto 30A ESC
|0.12
|5.3204e-05
|-
|DJI 2212/920 Old w/ 1045 Propeller & Old DJI Opto 30A ESC
|0.14
|6.2071e-05
|-
|DJI 2212/920 Old w/ 10in Carbon Fiber Propeller & Old DJI Opto 30A ESC
|0.24
|1.0641e-04
|}
72abc9623f358e87f40f0a0a00ca10b3702bfced
355
354
2016-10-17T20:13:13Z
Snawerdt
8
/* Motor Information */
wikitext
text/x-wiki
== Motor Information ==
{| class="wikitable"
|+Motor Information
|-
|
|Kv (RPM)
|Kv (rad/sec)
|Kq (rad/sec)
|If (A)
|Rm (Ohms)
|-
|DJI 2212/920 Old Motor
|920
|96.3422
|96.3422
|0.422
|0.243
|-
|DJI 2212/920 New Motor
|920
|96.3422
|96.3422
|0.511
|0.2308
|}
== Propeller Information ==
{| class="wikitable"
|+Propeller Information
|-
|
|Kt (kgm/rad^2)
|Kd (kgm^2/rad^2)
|-
|DJI 8045 8in
|2.3765e-07
|7.9008e-06
|-
|DJI 9443 9in
|9.5705e-06
|TBD
|-
|Carbon Fiber 9in
|1.2364e-05
|2.9011e-07
|-
|DJI 1045 10in
|1.1325e-05
|3.5388e-07
|}
== Motor & Propeller System Information ==
{| class="wikitable"
|+Propeller Information
|-
|
|Tau (sec)
|Jr (kgm^2)
|-
|DJI 2212/920 New w/ 9445 Propeller & New DJI Opto 30A ESC
|0.09
|TBD
|-
|DJI 2212/920 Old w/ 8045 Propeller & Old DJI Opto 30A ESC
|0.12
|5.3204e-05
|-
|DJI 2212/920 Old w/ 1045 Propeller & Old DJI Opto 30A ESC
|0.14
|6.2071e-05
|-
|DJI 2212/920 Old w/ 10in Carbon Fiber Propeller & Old DJI Opto 30A ESC
|0.24
|1.0641e-04
|}
e4bffd50f722bdc2719908ffc1c5dae1696643a1
356
355
2016-10-18T20:27:51Z
Imciner2
6
Added propeller constants for 9in DJI.
wikitext
text/x-wiki
== Motor Information ==
{| class="wikitable"
|+Motor Information
|-
|
|Kv (RPM)
|Kv (rad/sec)
|Kq (rad/sec)
|If (A)
|Rm (Ohms)
|-
|DJI 2212/920 Old Motor
|920
|96.3422
|96.3422
|0.422
|0.243
|-
|DJI 2212/920 New Motor
|920
|96.3422
|96.3422
|0.511
|0.2308
|}
== Propeller Information ==
{| class="wikitable"
|+Propeller Information
|-
|
|Kt (kgm/rad^2)
|Kd (kgm^2/rad^2)
|-
|DJI 8045 8in
|2.3765e-07
|7.9008e-06
|-
|DJI 9443 9in
|9.5705e-06
|6.1230e-06
|-
|Carbon Fiber 9in
|1.2364e-05
|2.9011e-07
|-
|DJI 1045 10in
|1.1325e-05
|3.5388e-07
|}
== Motor & Propeller System Information ==
{| class="wikitable"
|+Propeller Information
|-
|
|Tau (sec)
|Jr (kgm^2)
|-
|DJI 2212/920 New w/ 9445 Propeller & New DJI Opto 30A ESC
|0.09
|4.2012e-05
|-
|DJI 2212/920 Old w/ 8045 Propeller & Old DJI Opto 30A ESC
|0.12
|5.3204e-05
|-
|DJI 2212/920 Old w/ 1045 Propeller & Old DJI Opto 30A ESC
|0.14
|6.2071e-05
|-
|DJI 2212/920 Old w/ 10in Carbon Fiber Propeller & Old DJI Opto 30A ESC
|0.24
|1.0641e-04
|}
c2380023128ebb8fc7a0a7914aee758651185968
360
356
2017-02-21T19:36:59Z
M87rich
11
/* Motor Information */
wikitext
text/x-wiki
== Motor Information ==
{| class="wikitable"
|+Motor Information
|-
|
|Kv (RPM)
|Kv (rad/sec)
|Kq (rad/sec)
|<math>i_{f}</math> (A)
|Rm (Ohms)
|-
|DJI 2212/920 Old Motor
|920
|96.3422
|96.3422
|0.422
|0.243
|-
|DJI 2212/920 New Motor
|920
|96.3422
|96.3422
|0.511
|0.2308
|}
== Propeller Information ==
{| class="wikitable"
|+Propeller Information
|-
|
|Kt (kgm/rad^2)
|Kd (kgm^2/rad^2)
|-
|DJI 8045 8in
|2.3765e-07
|7.9008e-06
|-
|DJI 9443 9in
|9.5705e-06
|6.1230e-06
|-
|Carbon Fiber 9in
|1.2364e-05
|2.9011e-07
|-
|DJI 1045 10in
|1.1325e-05
|3.5388e-07
|}
== Motor & Propeller System Information ==
{| class="wikitable"
|+Propeller Information
|-
|
|Tau (sec)
|Jr (kgm^2)
|-
|DJI 2212/920 New w/ 9445 Propeller & New DJI Opto 30A ESC
|0.09
|4.2012e-05
|-
|DJI 2212/920 Old w/ 8045 Propeller & Old DJI Opto 30A ESC
|0.12
|5.3204e-05
|-
|DJI 2212/920 Old w/ 1045 Propeller & Old DJI Opto 30A ESC
|0.14
|6.2071e-05
|-
|DJI 2212/920 Old w/ 10in Carbon Fiber Propeller & Old DJI Opto 30A ESC
|0.24
|1.0641e-04
|}
be610fccf6b06c96571d1e29096ca1f3cb516f06
Distributed Autonomous and Networked Control Lab Wiki
0
1
357
350
2016-11-01T18:26:51Z
Dawehr
10
/* Projects */
wikitext
text/x-wiki
Welcome to the Distributed Autonomous and Networked Control Lab Wiki! Here you can find a wealth of information regarding the many projects we have running in the Lab.
Below are some of the projects we are working on:
'''
== Projects ==
'''
[[Crazyflie Swarm]]
[[Robotic Agriculture Data Acquisition (RADA)]]
[https://wikis.ece.iastate.edu/microcart-senior-design/index.php/Main_Page MicroCART]
[[Camera System and VRPN]]
'''
== Lab-Wide Information ==
[[Physical Parameters]] - Physical parameters for systems in the laboratory
If you can't find what you're looking for please feel free to contribute.
Consult the [http://meta.wikimedia.org/wiki/Help:Contents User's Guide] for information on using the wiki software.
== Lab Schedule ==
{| class="wikitable" style="text-align:center"
|+Reserved Lab Times
|-
! width="130"|Time !! width="130"|Monday !! width="130"|Tuesday !! width="130"|Wednesday !! width="130"|Thursday !! width="130"|Friday
|-
! 8am - 9am
| Open || Open || Open || Open || Open
|-
! 9am - 10am
| Open || Open || Open || Open || Open
|-
! 10am - 11am
| Open || style="background:orange"|CrazyFlie || Open || Open || Open
|-
! 11am - 12pm
| Open || style="background:orange"|CrazyFlie || Open || Open || Open
|-
! 12pm - 1pm
| Open || style="background:orange"|CrazyFlie|| Open || style="background:orange"|CrazyFlie || Open
|-
! 1pm - 2pm
| Open || style="background:green"|MicroCART Meeting || style="background:orange"|CrazyFlie || style="background:orange"|CrazyFlie || Open
|-
! 2pm - 3pm
| Open || Open ||style="background:orange"|CrazyFlie || style="background:orange"|CrazyFlie || Open
|-
! 3pm - 4pm
| Open || Open || style="background:orange"|CrazyFlie || style="background:green"|MicroCART || Open
|-
! 4pm - 5pm
| style="background:orange"|CrazyFlie Meeting || style="background:teal"|RADA || style="background:teal"|RADA Meeting || style="background:green"|MicroCART || style="background:green"|MicroCART
|-
! 5pm - 6pm
| style="background:teal"|RADA || style="background:teal"|RADA || style="background:teal"|RADA || Open || style="background:green"|MicroCART
|-
! 6pm - 7pm
| style="background:teal"|RADA || style="background:teal"|RADA || style="background:teal"|RADA || Open || Open
|-
! 7pm - 8pm
| Open || Open || Open || Open || Open
|-
! 8pm - 9pm
| Open || Open || Open || Open || Open
|-
! 9pm - 10pm
| Open || Open || Open || Open || Open
|}
== Getting Started ==
* [http://www.mediawiki.org/wiki/Manual:Configuration_settings Configuration settings list]
* [http://www.mediawiki.org/wiki/Manual:FAQ MediaWiki FAQ]
* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce MediaWiki release mailing list]
95f93bd1b5a3972912ed205e655f1f4020c78f06
366
357
2017-09-18T21:50:54Z
Rbuckley
12
/* Lab Schedule */
wikitext
text/x-wiki
Welcome to the Distributed Autonomous and Networked Control Lab Wiki! Here you can find a wealth of information regarding the many projects we have running in the Lab.
Below are some of the projects we are working on:
'''
== Projects ==
'''
[[Crazyflie Swarm]]
[[Robotic Agriculture Data Acquisition (RADA)]]
[https://wikis.ece.iastate.edu/microcart-senior-design/index.php/Main_Page MicroCART]
[[Camera System and VRPN]]
'''
== Lab-Wide Information ==
[[Physical Parameters]] - Physical parameters for systems in the laboratory
If you can't find what you're looking for please feel free to contribute.
Consult the [http://meta.wikimedia.org/wiki/Help:Contents User's Guide] for information on using the wiki software.
== Lab Schedule ==
{| class="wikitable" style="text-align:center"
|+Reserved Lab Times
|-
! width="130"|Time !! width="130"|Monday !! width="130"|Tuesday !! width="130"|Wednesday !! width="130"|Thursday !! width="130"|Friday
|-
! 8am - 9am
| Open || Open || Open || Open || Open
|-
! 9am - 10am
| Open || Open || Open || Open || Open
|-
! 10am - 11am
| Open || Open || Open || Open || Open
|-
! 11am - 12pm
| Open || Open || Open || Open || Open
|-
! 12pm - 1pm
| Open || Open || Open || open || Open
|-
! 1pm - 2pm
| Open || Open || Open || Open || Open
|-
! 2pm - 3pm
| Open || Open || Open || style="background:green"| Meeting || Open
|-
! 3pm - 4pm
| Open || Open || Open || style="background:green"| Meeting || Open
|-
! 4pm - 5pm
| Open || style="background:green"|MicroCART Meeting || Open || Open || style="background:green"| Meeting
|-
! 5pm - 6pm
| Open || Open || Open || Open || style="background:green"| Meeting
|-
! 6pm - 7pm
| Open || Open || Open || Open || style="background:green"| Meeting
|-
! 7pm - 8pm
| Open || Open || Open || Open || style="background:green"| Meeting
|-
! 8pm - 9pm
| Open || Open || Open || Open || style="background:green"| Meeting
|-
! 9pm - 10pm
| Open || Open || Open || Open || style="background:green"| Meeting
|}
== Getting Started ==
* [http://www.mediawiki.org/wiki/Manual:Configuration_settings Configuration settings list]
* [http://www.mediawiki.org/wiki/Manual:FAQ MediaWiki FAQ]
* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce MediaWiki release mailing list]
7132d3dcbacaf7fe262599654c61426920851120
367
366
2017-09-18T21:52:59Z
Rbuckley
12
/* Lab Schedule */
wikitext
text/x-wiki
Welcome to the Distributed Autonomous and Networked Control Lab Wiki! Here you can find a wealth of information regarding the many projects we have running in the Lab.
Below are some of the projects we are working on:
'''
== Projects ==
'''
[[Crazyflie Swarm]]
[[Robotic Agriculture Data Acquisition (RADA)]]
[https://wikis.ece.iastate.edu/microcart-senior-design/index.php/Main_Page MicroCART]
[[Camera System and VRPN]]
'''
== Lab-Wide Information ==
[[Physical Parameters]] - Physical parameters for systems in the laboratory
If you can't find what you're looking for please feel free to contribute.
Consult the [http://meta.wikimedia.org/wiki/Help:Contents User's Guide] for information on using the wiki software.
== Lab Schedule ==
{| class="wikitable" style="text-align:center"
|+Reserved Lab Times
|-
! width="130"|Time !! width="130"|Monday !! width="130"|Tuesday !! width="130"|Wednesday !! width="130"|Thursday !! width="130"|Friday
|-
! 8am - 9am
| Open || Open || Open || Open || Open
|-
! 9am - 10am
| Open || Open || Open || Open || Open
|-
! 10am - 11am
| Open || Open || Open || Open || Open
|-
! 11am - 12pm
| Open || Open || Open || Open || Open
|-
! 12pm - 1pm
| Open || Open || Open || open || Open
|-
! 1pm - 2pm
| Open || Open || Open || Open || Open
|-
! 2pm - 3pm
| Open || Open || Open || style="background:green"| MicroCART || Open
|-
! 3pm - 4pm
| Open || Open || Open || style="background:green"| MicroCART || Open
|-
! 4pm - 5pm
| Open || style="background:green"|MicroCART Meeting || Open || Open || style="background:green"| MicroCART
|-
! 5pm - 6pm
| Open || Open || Open || Open || style="background:green"| MicroCART
|-
! 6pm - 7pm
| Open || Open || Open || Open || style="background:green"| MicroCART
|-
! 7pm - 8pm
| Open || Open || Open || Open || style="background:green"| MicroCART
|-
! 8pm - 9pm
| Open || Open || Open || Open || style="background:green"| MicroCART
|-
! 9pm - 10pm
| Open || Open || Open || Open || style="background:green"| MicroCART
|}
== Getting Started ==
* [http://www.mediawiki.org/wiki/Manual:Configuration_settings Configuration settings list]
* [http://www.mediawiki.org/wiki/Manual:FAQ MediaWiki FAQ]
* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce MediaWiki release mailing list]
1a7d1131613cbd99b053d9009b588a75aabdd521
368
367
2017-09-18T22:30:44Z
Rbuckley
12
wikitext
text/x-wiki
Welcome to the Distributed Autonomous and Networked Control Lab Wiki! Here you can find a wealth of information regarding the many projects we have running in the Lab.
Below are some of the projects we are working on:
'''
== Projects ==
'''
[[Crazyflie Swarm]]
[[Robotic Agriculture Data Acquisition (RADA)]]
[https://wikis.ece.iastate.edu/microcart-senior-design/index.php/Main_Page MicroCART]
[[Camera System and VRPN]]
'''
== Lab-Wide Information ==
[[Physical Parameters]] - Physical parameters for systems in the laboratory
If you can't find what you're looking for please feel free to contribute.
Consult the [http://meta.wikimedia.org/wiki/Help:Contents User's Guide] for information on using the wiki software.
== Lab Schedule ==
{| class="wikitable" style="text-align:center"
|+Reserved Lab Times
|-
! width="130"|Time !! width="130"|Monday !! width="130"|Tuesday !! width="130"|Wednesday !! width="130"|Thursday !! width="130"|Friday
|-
! 8am - 9am
| Open || Open || Open || Open || Open
|-
! 9am - 10am
| Open || Open || Open || Open || Open
|-
! 10am - 11am
| Open || style="background:orange"|CrazyFlie || Open || Open || Open
|-
! 11am - 12pm
| Open || style="background:orange"|CrazyFlie || Open || Open || Open
|-
! 12pm - 1pm
| Open || style="background:orange"|CrazyFlie|| Open || style="background:orange"|CrazyFlie || Open
|-
! 1pm - 2pm
| Open || style="background:green"|MicroCART Meeting || style="background:orange"|CrazyFlie || style="background:orange"|CrazyFlie || Open
|-
! 2pm - 3pm
| Open || Open ||style="background:orange"|CrazyFlie || style="background:orange"|CrazyFlie || Open
|-
! 3pm - 4pm
| Open || Open || style="background:orange"|CrazyFlie || style="background:green"|MicroCART || Open
|-
! 4pm - 5pm
| style="background:orange"|CrazyFlie Meeting || style="background:teal"|RADA || style="background:teal"|RADA Meeting || style="background:green"|MicroCART || style="background:green"|MicroCART
|-
! 5pm - 6pm
| style="background:teal"|RADA || style="background:teal"|RADA || style="background:teal"|RADA || Open || style="background:green"|MicroCART
|-
! 6pm - 7pm
| style="background:teal"|RADA || style="background:teal"|RADA || style="background:teal"|RADA || Open || Open
|-
! 7pm - 8pm
| Open || Open || Open || Open || Open
|-
! 8pm - 9pm
| Open || Open || Open || Open || Open
|-
! 9pm - 10pm
| Open || Open || Open || Open || Open
|}
== Getting Started ==
* [http://www.mediawiki.org/wiki/Manual:Configuration_settings Configuration settings list]
* [http://www.mediawiki.org/wiki/Manual:FAQ MediaWiki FAQ]
* [https://lists.wikimedia.org/mailman/listinfo/mediawiki-announce MediaWiki release mailing list]
95f93bd1b5a3972912ed205e655f1f4020c78f06
Camera System and VRPN
0
84
358
2017-02-01T00:31:01Z
Imciner2
6
Created page with " == Tracking Tools Software == === Resetting Orientation === The camera system Tracking Tools software includes a feature to "Reset Orientation" of the currently selected tr..."
wikitext
text/x-wiki
== Tracking Tools Software ==
=== Resetting Orientation ===
The camera system Tracking Tools software includes a feature to "Reset Orientation" of the currently selected trackable. This feature will only bias the angular position (basically subtract off the current values from the calculated angles), and will not rotate the coordinate system of the trackable to match the new orientation. '''This feature cannot be used to modify the coordinate system.'''
e31583e940e9b02fdf95b36795f534d2605be8ce
359
358
2017-02-01T00:39:30Z
Imciner2
6
/* Tracking Tools Software */
wikitext
text/x-wiki
== Tracking Tools Software ==
=== Angular Display ===
The Tracking Tools software includes a display of the trackable's current position (X,Y,Z and attitude). The X, Y, Z values displayed are relative to the camera system's coordinate axis. The attitude displayed is in Euler Angles relative to the camera's coordinate system (its inertial frame). The sequence of Euler angles it uses to convert into these angles '''is not the Yaw-Pitch-Roll (Aerospace) sequence.'''
=== Resetting Orientation ===
The camera system Tracking Tools software includes a feature to "Reset Orientation" of the currently selected trackable. This feature will only bias the angular position (basically subtract off the current values from the calculated angles), and will not rotate the coordinate system of the trackable to match the new orientation. '''This feature cannot be used to modify the coordinate system.'''
1d5c136c676a20052577a8f3a7efe45b8d64ffa3
361
359
2017-04-24T20:36:10Z
Imciner2
6
wikitext
text/x-wiki
== Calibrating The Cameras ==
=== Setting the Ground Plane ===
== Tracking Tools Software ==
=== Angular Display ===
The Tracking Tools software includes a display of the trackable's current position (X,Y,Z and attitude). The X, Y, Z values displayed are relative to the camera system's coordinate axis. The attitude displayed is in Euler Angles relative to the camera's coordinate system (its inertial frame). The sequence of Euler angles it uses to convert into these angles '''is not the Yaw-Pitch-Roll (Aerospace) sequence.'''
=== Resetting Orientation ===
The camera system Tracking Tools software includes a feature to "Reset Orientation" of the currently selected trackable. This feature will only bias the angular position (basically subtract off the current values from the calculated angles), and will not rotate the coordinate system of the trackable to match the new orientation. '''This feature cannot be used to modify the coordinate system.'''
ece16d7e321be80198970e3c8fdf9f0ab5df2ce9
363
361
2017-04-24T20:47:17Z
Imciner2
6
/* Setting the Ground Plane */
wikitext
text/x-wiki
== Calibrating The Cameras ==
=== Setting the Ground Plane ===
In order to setup the axis system for the camera system, the ground plane tool needs to be used. It has 3 trackables on it, and form an L shape. The negative Z axis is marked by the arrow (so it is negative in that direction). The X axis is the other arm.
To orient it, place it so that the short leg of the L faces east (towards the whiteboards), and the long leg pointing towards the ceiling. In order to get this oriented, it needs to be supported as shown in the image below. When aligning it, also use the level and make sure the long leg is perpendicular to the floor (it may be necessary to prop it up to make it perpendicular).
Once the tool is set, select the three trackables in the software window. Then inside the "Ground Plane" tab, click on the "Set Ground Plane" button to create the axis system.
[[File:CameraGroundPlane.jpg|300px|Ground plane configuration for the camera system]]
== Tracking Tools Software ==
=== Angular Display ===
The Tracking Tools software includes a display of the trackable's current position (X,Y,Z and attitude). The X, Y, Z values displayed are relative to the camera system's coordinate axis. The attitude displayed is in Euler Angles relative to the camera's coordinate system (its inertial frame). The sequence of Euler angles it uses to convert into these angles '''is not the Yaw-Pitch-Roll (Aerospace) sequence.'''
=== Resetting Orientation ===
The camera system Tracking Tools software includes a feature to "Reset Orientation" of the currently selected trackable. This feature will only bias the angular position (basically subtract off the current values from the calculated angles), and will not rotate the coordinate system of the trackable to match the new orientation. '''This feature cannot be used to modify the coordinate system.'''
73731c5d61fd40e5fb4a5d992628151124abc78c
364
363
2017-04-28T16:18:21Z
Imciner2
6
wikitext
text/x-wiki
== Calibrating The Cameras ==
=== Setting the Ground Plane ===
In order to setup the axis system for the camera system, the ground plane tool needs to be used. It has 3 trackables on it, and form an L shape. The negative Z axis is marked by the arrow (so it is negative in that direction). The X axis is the other arm.
To orient it, place it so that the short leg of the L faces east (towards the whiteboards), and the long leg pointing towards the ceiling. In order to get this oriented, it needs to be supported as shown in the image below. When aligning it, also use the level and make sure the long leg is perpendicular to the floor (it may be necessary to prop it up to make it perpendicular).
Once the tool is set, select the three trackables in the software window. Then inside the "Ground Plane" tab, click on the "Set Ground Plane" button to create the axis system.
[[File:CameraGroundPlane.jpg|300px|Ground plane configuration for the camera system]]
== Tracking Tools Software ==
=== Angular Display ===
The Tracking Tools software includes a display of the trackable's current position (X,Y,Z and attitude). The X, Y, Z values displayed are relative to the camera system's coordinate axis. The attitude displayed is in Euler Angles relative to the camera's coordinate system (its inertial frame). The sequence of Euler angles it uses to convert into these angles '''is not the Yaw-Pitch-Roll (Aerospace) sequence.'''
=== Resetting Orientation ===
The camera system Tracking Tools software includes a feature to "Reset Orientation" of the currently selected trackable. This feature will only bias the angular position (basically subtract off the current values from the calculated angles), and will not rotate the coordinate system of the trackable to match the new orientation. '''This feature cannot be used to modify the coordinate system.'''
== Computer Configuration ==
=== Windows Settings ===
It appears that Tracking Tools has an incompatibility with some updates provided with Windows 7. The problem is the VRPN server is unable to consistently maintain an update interval of 10ms position packets (the software still gets position at 10ms intervals, but it is not reported over VRPN at that rate).
To fix this, the Tracking Tools software must be run on a non-updated version of Windows 7 (it appears updates released sometime in 2015-2016 broke the VRPN function). So Windows Update should be disabled.
Additionally, system restore should be enabled (for both settings and files), so that in the future if anything happens the system can be reverted to a known-working state.
ef785413ccce88cb40e1115b7d46090777b132c6
365
364
2017-04-28T16:20:11Z
Imciner2
6
wikitext
text/x-wiki
== System Overview ==
The VRPN system operates on IP address 192.168.0.120 port 3883/
== Calibrating The Cameras ==
=== Setting the Ground Plane ===
In order to setup the axis system for the camera system, the ground plane tool needs to be used. It has 3 trackables on it, and form an L shape. The negative Z axis is marked by the arrow (so it is negative in that direction). The X axis is the other arm.
To orient it, place it so that the short leg of the L faces east (towards the whiteboards), and the long leg pointing towards the ceiling. In order to get this oriented, it needs to be supported as shown in the image below. When aligning it, also use the level and make sure the long leg is perpendicular to the floor (it may be necessary to prop it up to make it perpendicular).
Once the tool is set, select the three trackables in the software window. Then inside the "Ground Plane" tab, click on the "Set Ground Plane" button to create the axis system.
[[File:CameraGroundPlane.jpg|300px|Ground plane configuration for the camera system]]
== Tracking Tools Software ==
=== Angular Display ===
The Tracking Tools software includes a display of the trackable's current position (X,Y,Z and attitude). The X, Y, Z values displayed are relative to the camera system's coordinate axis. The attitude displayed is in Euler Angles relative to the camera's coordinate system (its inertial frame). The sequence of Euler angles it uses to convert into these angles '''is not the Yaw-Pitch-Roll (Aerospace) sequence.'''
=== Resetting Orientation ===
The camera system Tracking Tools software includes a feature to "Reset Orientation" of the currently selected trackable. This feature will only bias the angular position (basically subtract off the current values from the calculated angles), and will not rotate the coordinate system of the trackable to match the new orientation. '''This feature cannot be used to modify the coordinate system.'''
== Computer Configuration ==
=== Windows Settings ===
It appears that Tracking Tools has an incompatibility with some updates provided with Windows 7. The problem is the VRPN server is unable to consistently maintain an update interval of 10ms position packets (the software still gets position at 10ms intervals, but it is not reported over VRPN at that rate).
To fix this, the Tracking Tools software must be run on a non-updated version of Windows 7 (it appears updates released sometime in 2015-2016 broke the VRPN function). So Windows Update should be disabled.
Additionally, system restore should be enabled (for both settings and files), so that in the future if anything happens the system can be reverted to a known-working state.
=== Firewall Settings ===
The Windows computer hosting the VRPN server must have port 3883 both TCP and UDP protocols opened in order to work.
Additionally, all clients should have those two ports opened as well. Since VRPN appears to create connections in both directions.
82327bd0d817d8c27b49cf134ef8367621f25207
File:CameraGroundPlane.jpg
6
85
362
2017-04-24T20:37:58Z
Imciner2
6
Ground plane orientation for the camera system calibration.
wikitext
text/x-wiki
Ground plane orientation for the camera system calibration.
bce94eb616b22f6d3c56ecb710d7b984f97d3874